diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx
index 67faf8d646..88dc4a7207 100644
--- a/packages/app-next/src/App.tsx
+++ b/packages/app-next/src/App.tsx
@@ -29,6 +29,7 @@ import {
createExtension,
createApiExtension,
createExtensionOverrides,
+ createNotFoundErrorPageExtension,
} from '@backstage/frontend-plugin-api';
import techdocsPlugin from '@backstage/plugin-techdocs/alpha';
import { homePage } from './HomePage';
@@ -48,6 +49,8 @@ import {
} from '@backstage/integration-react';
import { createSignInPageExtension } from '@backstage/frontend-plugin-api';
import { SignInPage } from '@backstage/core-components';
+import { Box, Typography } from '@material-ui/core';
+import { Button } from '@backstage/core-components';
/*
@@ -108,6 +111,40 @@ const scmIntegrationApi = createApiExtension({
}),
});
+const customNotFoundErrorPage = createNotFoundErrorPageExtension({
+ component: () => (
+
+ 404
+
+ Bowie was unable to locate this page. Please contact your support team
+ if this page used to exist.
+
+
+
+
+ ),
+});
+
const collectedLegacyPlugins = collectLegacyRoutes(
} />
@@ -129,6 +166,7 @@ const app = createApp({
scmAuthExtension,
scmIntegrationApi,
signInPage,
+ customNotFoundErrorPage,
],
}),
],
diff --git a/packages/frontend-app-api/src/extensions/CoreComponents.tsx b/packages/frontend-app-api/src/extensions/CoreComponents.tsx
index 3e1bc8e8bc..a0651d6423 100644
--- a/packages/frontend-app-api/src/extensions/CoreComponents.tsx
+++ b/packages/frontend-app-api/src/extensions/CoreComponents.tsx
@@ -19,12 +19,36 @@ import {
createExtension,
coreExtensionData,
createExtensionInput,
+ createProgressExtension,
+ createBootErrorPageExtension,
+ createNotFoundErrorPageExtension,
+ createErrorBoundaryFallbackExtension,
} from '@backstage/frontend-plugin-api';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
+import { components as defaultComponents } from '../../../app-defaults/src/defaults';
+// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { AppContextProvider } from '../../../core-app-api/src/app/AppContext';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { useApp } from '../../../core-plugin-api/src/app/useApp';
+export const DefaultProgressComponent = createProgressExtension({
+ component: defaultComponents.Progress,
+});
+
+export const DefaultBootErrorPageComponent = createBootErrorPageExtension({
+ component: defaultComponents.BootErrorPage,
+});
+
+export const DefaultNotFoundErrorPageComponent =
+ createNotFoundErrorPageExtension({
+ component: defaultComponents.NotFoundErrorPage,
+ });
+
+export const DefaultErrorBoundaryComponent =
+ createErrorBoundaryFallbackExtension({
+ component: defaultComponents.ErrorBoundaryFallback,
+ });
+
export const CoreComponents = createExtension({
id: 'core.components',
attachTo: { id: 'core', input: 'components' },
diff --git a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx b/packages/frontend-app-api/src/extensions/CoreRoutes.tsx
index 985fd07be9..e2798c091d 100644
--- a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx
+++ b/packages/frontend-app-api/src/extensions/CoreRoutes.tsx
@@ -21,6 +21,8 @@ import {
createExtensionInput,
} from '@backstage/frontend-plugin-api';
import { useRoutes } from 'react-router-dom';
+// eslint-disable-next-line @backstage/no-relative-monorepo-imports
+import { useApp } from '../../../core-plugin-api/src/app/useApp';
export const CoreRoutes = createExtension({
id: 'core.routes',
@@ -37,12 +39,18 @@ export const CoreRoutes = createExtension({
},
factory({ inputs }) {
const Routes = () => {
- const element = useRoutes(
- inputs.routes.map(route => ({
+ const app = useApp();
+ const { NotFoundErrorPage } = app.getComponents();
+ const element = useRoutes([
+ ...inputs.routes.map(route => ({
path: `${route.path}/*`,
element: route.element,
})),
- );
+ {
+ path: '*',
+ element: ,
+ },
+ ]);
return element;
};
diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx
index 8d51df84c0..caa7064b2d 100644
--- a/packages/frontend-app-api/src/wiring/createApp.tsx
+++ b/packages/frontend-app-api/src/wiring/createApp.tsx
@@ -89,7 +89,13 @@ import { RoutingProvider } from '../routing/RoutingProvider';
import { resolveRouteBindings } from '../routing/resolveRouteBindings';
import { collectRouteIds } from '../routing/collectRouteIds';
import { createAppTree } from '../tree';
-import { CoreComponents } from '../extensions/CoreComponents';
+import {
+ CoreComponents,
+ DefaultProgressComponent,
+ DefaultErrorBoundaryComponent,
+ DefaultBootErrorPageComponent,
+ DefaultNotFoundErrorPageComponent,
+} from '../extensions/CoreComponents';
import { AppNode } from '@backstage/frontend-plugin-api';
import { toLegacyPlugin } from '../routing/toLegacyPlugin';
import { InternalAppContext } from './InternalAppContext';
@@ -106,6 +112,10 @@ const builtinExtensions = [
CoreNav,
CoreLayout,
CoreComponents,
+ DefaultProgressComponent,
+ DefaultErrorBoundaryComponent,
+ DefaultBootErrorPageComponent,
+ DefaultNotFoundErrorPageComponent,
LightTheme,
DarkTheme,
];
diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx
new file mode 100644
index 0000000000..5c882dd638
--- /dev/null
+++ b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2023 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.
+ */
+
+// eslint-disable-next-line @backstage/no-relative-monorepo-imports
+import { AppComponents } from '../../../core-app-api/src/app/types';
+import { coreExtensionData, createExtension } from '../wiring';
+
+/** @public */
+export function createBootErrorPageExtension(options: {
+ component: AppComponents['BootErrorPage'];
+}) {
+ return createExtension({
+ id: `core.components.bootErrorPage`,
+ attachTo: { id: 'core.components', input: 'bootErrorPage' },
+ inputs: {},
+ output: {
+ component: coreExtensionData.components.bootErrorPage,
+ },
+ factory({ bind }) {
+ bind({
+ component: options.component,
+ });
+ },
+ });
+}
+
+/** @public */
+export function createNotFoundErrorPageExtension(options: {
+ component: AppComponents['NotFoundErrorPage'];
+}) {
+ return createExtension({
+ id: `core.components.notFoundErrorPage`,
+ attachTo: { id: 'core.components', input: 'notFoundErrorPage' },
+ inputs: {},
+ output: {
+ component: coreExtensionData.components.notFoundErrorPage,
+ },
+ factory({ bind }) {
+ bind({
+ component: options.component,
+ });
+ },
+ });
+}
+
+/** @public */
+export function createErrorBoundaryFallbackExtension(options: {
+ component: AppComponents['ErrorBoundaryFallback'];
+}) {
+ return createExtension({
+ id: `core.components.errorBoundaryFallback`,
+ attachTo: { id: 'core.components', input: 'errorBoundaryFallback' },
+ inputs: {},
+ output: {
+ component: coreExtensionData.components.errorBoundaryFallback,
+ },
+ factory({ bind }) {
+ bind({
+ component: options.component,
+ });
+ },
+ });
+}
+
+/** @public */
+export function createProgressExtension(options: {
+ component: AppComponents['Progress'];
+}) {
+ return createExtension({
+ id: `core.components.progress`,
+ attachTo: { id: 'core.components', input: 'progress' },
+ inputs: {},
+ output: {
+ component: coreExtensionData.components.progress,
+ },
+ factory({ bind }) {
+ bind({
+ component: options.component,
+ });
+ },
+ });
+}
diff --git a/packages/frontend-plugin-api/src/extensions/index.ts b/packages/frontend-plugin-api/src/extensions/index.ts
index d696774272..d036cb5dda 100644
--- a/packages/frontend-plugin-api/src/extensions/index.ts
+++ b/packages/frontend-plugin-api/src/extensions/index.ts
@@ -19,3 +19,9 @@ export { createPageExtension } from './createPageExtension';
export { createNavItemExtension } from './createNavItemExtension';
export { createSignInPageExtension } from './createSignInPageExtension';
export { createThemeExtension } from './createThemeExtension';
+export {
+ createProgressExtension,
+ createBootErrorPageExtension,
+ createNotFoundErrorPageExtension,
+ createErrorBoundaryFallbackExtension,
+} from './createComponentExtension';