diff --git a/packages/frontend-plugin-api/src/extensions/SignInPageBlueprint.test.tsx b/packages/frontend-plugin-api/src/extensions/SignInPageBlueprint.test.tsx
new file mode 100644
index 0000000000..7bbeb4e5d7
--- /dev/null
+++ b/packages/frontend-plugin-api/src/extensions/SignInPageBlueprint.test.tsx
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import { SignInPageBlueprint } from './SignInPageBlueprint';
+import { createExtensionTester } from '@backstage/frontend-test-utils';
+import { waitFor } from '@testing-library/react';
+
+describe('SignInPageBlueprint', () => {
+ it('should create an extension with sensible defaults', () => {
+ expect(
+ SignInPageBlueprint.make({
+ params: { loader: async () => () =>
},
+ }),
+ ).toMatchInlineSnapshot(`
+ {
+ "$$type": "@backstage/ExtensionDefinition",
+ "attachTo": {
+ "id": "app/root",
+ "input": "signInPage",
+ },
+ "configSchema": undefined,
+ "disabled": false,
+ "factory": [Function],
+ "inputs": {},
+ "kind": "sign-in-page",
+ "name": undefined,
+ "namespace": undefined,
+ "output": [
+ [Function],
+ ],
+ "toString": [Function],
+ "version": "v2",
+ }
+ `);
+ });
+
+ it('should return the component as the componentRef', async () => {
+ const MockSignInPage = () => MockSignInPage
;
+
+ const extension = SignInPageBlueprint.make({
+ params: { loader: async () => () => },
+ });
+
+ const tester = createExtensionTester(extension);
+ expect(tester.data(SignInPageBlueprint.dataRefs.component)).toBeDefined();
+
+ const { getByText } = tester.render();
+
+ // todo(blam): need a better way to test this, currently fails.
+ await waitFor(() => {
+ expect(getByText('MockSignInPage')).toBeInTheDocument();
+ });
+ });
+});
diff --git a/packages/frontend-plugin-api/src/extensions/SignInPageBlueprint.tsx b/packages/frontend-plugin-api/src/extensions/SignInPageBlueprint.tsx
new file mode 100644
index 0000000000..01ba174efe
--- /dev/null
+++ b/packages/frontend-plugin-api/src/extensions/SignInPageBlueprint.tsx
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { ComponentType, lazy } from 'react';
+import { createExtensionBlueprint } from '../wiring';
+import { createSignInPageExtension } from './createSignInPageExtension';
+import { SignInPageProps } from '@backstage/core-plugin-api';
+import { ExtensionBoundary } from '../components';
+
+export const SignInPageBlueprint = createExtensionBlueprint({
+ kind: 'sign-in-page',
+ attachTo: { id: 'app/root', input: 'signInPage' },
+ output: [createSignInPageExtension.componentDataRef],
+ dataRefs: {
+ component: createSignInPageExtension.componentDataRef,
+ },
+ *factory(
+ {
+ loader,
+ }: {
+ loader: (opts: {
+ config: typeof config;
+ inputs: typeof inputs;
+ }) => Promise>;
+ },
+ { config, inputs, node },
+ ) {
+ const ExtensionComponent = lazy(() =>
+ loader({ config, inputs }).then(component => ({ default: component })),
+ );
+
+ yield createSignInPageExtension.componentDataRef(props => (
+
+
+
+ ));
+ },
+});