diff --git a/.changeset/olive-walls-wonder.md b/.changeset/olive-walls-wonder.md
new file mode 100644
index 0000000000..ef8d37272e
--- /dev/null
+++ b/.changeset/olive-walls-wonder.md
@@ -0,0 +1,7 @@
+---
+'@backstage/frontend-app-api': minor
+'@backstage/frontend-plugin-api': minor
+'@backstage/frontend-test-utils': patch
+---
+
+Rename the `app/router` extension to `app/root`.
diff --git a/packages/frontend-app-api/src/extensions/Core.tsx b/packages/frontend-app-api/src/extensions/App.tsx
similarity index 97%
rename from packages/frontend-app-api/src/extensions/Core.tsx
rename to packages/frontend-app-api/src/extensions/App.tsx
index ea722ce862..751a255fa7 100644
--- a/packages/frontend-app-api/src/extensions/Core.tsx
+++ b/packages/frontend-app-api/src/extensions/App.tsx
@@ -24,7 +24,7 @@ import {
createTranslationExtension,
} from '@backstage/frontend-plugin-api';
-export const Core = createExtension({
+export const App = createExtension({
namespace: 'app',
attachTo: { id: 'root', input: 'default' }, // ignored
inputs: {
diff --git a/packages/frontend-app-api/src/extensions/CoreLayout.tsx b/packages/frontend-app-api/src/extensions/AppLayout.tsx
similarity index 93%
rename from packages/frontend-app-api/src/extensions/CoreLayout.tsx
rename to packages/frontend-app-api/src/extensions/AppLayout.tsx
index 2d65dff73a..7be0029c25 100644
--- a/packages/frontend-app-api/src/extensions/CoreLayout.tsx
+++ b/packages/frontend-app-api/src/extensions/AppLayout.tsx
@@ -22,10 +22,10 @@ import {
} from '@backstage/frontend-plugin-api';
import { SidebarPage } from '@backstage/core-components';
-export const CoreLayout = createExtension({
+export const AppLayout = createExtension({
namespace: 'app',
name: 'layout',
- attachTo: { id: 'app/router', input: 'children' },
+ attachTo: { id: 'app/root', input: 'children' },
inputs: {
nav: createExtensionInput(
{
diff --git a/packages/frontend-app-api/src/extensions/CoreNav.tsx b/packages/frontend-app-api/src/extensions/AppNav.tsx
similarity index 98%
rename from packages/frontend-app-api/src/extensions/CoreNav.tsx
rename to packages/frontend-app-api/src/extensions/AppNav.tsx
index 9c0ac5e85a..c5bf028ef8 100644
--- a/packages/frontend-app-api/src/extensions/CoreNav.tsx
+++ b/packages/frontend-app-api/src/extensions/AppNav.tsx
@@ -78,7 +78,7 @@ const SidebarNavItem = (
return ;
};
-export const CoreNav = createExtension({
+export const AppNav = createExtension({
namespace: 'app',
name: 'nav',
attachTo: { id: 'app/layout', input: 'nav' },
diff --git a/packages/frontend-app-api/src/extensions/CoreRouter.tsx b/packages/frontend-app-api/src/extensions/AppRoot.tsx
similarity index 98%
rename from packages/frontend-app-api/src/extensions/CoreRouter.tsx
rename to packages/frontend-app-api/src/extensions/AppRoot.tsx
index 5c823c2e60..0894287541 100644
--- a/packages/frontend-app-api/src/extensions/CoreRouter.tsx
+++ b/packages/frontend-app-api/src/extensions/AppRoot.tsx
@@ -34,9 +34,9 @@ import { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations
import { BrowserRouter } from 'react-router-dom';
import { RouteTracker } from '../routing/RouteTracker';
-export const CoreRouter = createExtension({
+export const AppRoot = createExtension({
namespace: 'app',
- name: 'router',
+ name: 'root',
attachTo: { id: 'app', input: 'root' },
inputs: {
signInPage: createExtensionInput(
diff --git a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx b/packages/frontend-app-api/src/extensions/AppRoutes.tsx
similarity index 97%
rename from packages/frontend-app-api/src/extensions/CoreRoutes.tsx
rename to packages/frontend-app-api/src/extensions/AppRoutes.tsx
index d66c857f3b..38a9291755 100644
--- a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx
+++ b/packages/frontend-app-api/src/extensions/AppRoutes.tsx
@@ -24,7 +24,7 @@ import {
} from '@backstage/frontend-plugin-api';
import { useRoutes } from 'react-router-dom';
-export const CoreRoutes = createExtension({
+export const AppRoutes = createExtension({
namespace: 'app',
name: 'routes',
attachTo: { id: 'app/layout', input: 'content' },
@@ -57,6 +57,7 @@ export const CoreRoutes = createExtension({
return element;
};
+
return {
element: ,
};
diff --git a/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts b/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts
index 4531947f9a..440407549e 100644
--- a/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts
+++ b/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts
@@ -25,18 +25,18 @@ describe('readAppExtensionsConfig', () => {
it('should disable extension with shorthand notation', () => {
expect(
readAppExtensionsConfig(
- new ConfigReader({ app: { extensions: [{ 'app/router': false }] } }),
+ new ConfigReader({ app: { extensions: [{ 'app/root': false }] } }),
),
).toEqual([
{
- id: 'app/router',
+ id: 'app/root',
disabled: true,
},
]);
expect(
readAppExtensionsConfig(
new ConfigReader({
- app: { extensions: [{ 'app/router': { disabled: true } }] },
+ app: { extensions: [{ 'app/root': { disabled: true } }] },
}),
),
).toEqual([
@@ -44,7 +44,7 @@ describe('readAppExtensionsConfig', () => {
at: undefined,
config: undefined,
disabled: true,
- id: 'app/router',
+ id: 'app/root',
},
]);
});
@@ -52,33 +52,33 @@ describe('readAppExtensionsConfig', () => {
it('should enable extension with shorthand notation', () => {
expect(
readAppExtensionsConfig(
- new ConfigReader({ app: { extensions: ['app/router'] } }),
+ new ConfigReader({ app: { extensions: ['app/root'] } }),
),
).toEqual([
{
- id: 'app/router',
+ id: 'app/root',
disabled: false,
},
]);
expect(
readAppExtensionsConfig(
- new ConfigReader({ app: { extensions: [{ 'app/router': true }] } }),
+ new ConfigReader({ app: { extensions: [{ 'app/root': true }] } }),
),
).toEqual([
{
- id: 'app/router',
+ id: 'app/root',
disabled: false,
},
]);
expect(
readAppExtensionsConfig(
new ConfigReader({
- app: { extensions: [{ 'app/router': { disabled: false } }] },
+ app: { extensions: [{ 'app/root': { disabled: false } }] },
}),
),
).toEqual([
{
- id: 'app/router',
+ id: 'app/root',
disabled: false,
},
]);
@@ -89,12 +89,12 @@ describe('readAppExtensionsConfig', () => {
readAppExtensionsConfig(
new ConfigReader({
app: {
- extensions: [{ 'app/router': 'some-string' }],
+ extensions: [{ 'app/root': 'some-string' }],
},
}),
),
).toThrow(
- 'Invalid extension configuration at app.extensions[0][app/router], value must be a boolean or object',
+ 'Invalid extension configuration at app.extensions[0][app/root], value must be a boolean or object',
);
});
@@ -156,8 +156,8 @@ describe('expandShorthandExtensionParameters', () => {
});
it('supports string key', () => {
- expect(run('app/router')).toEqual({
- id: 'app/router',
+ expect(run('app/root')).toEqual({
+ id: 'app/root',
disabled: false,
});
expect(() => run('')).toThrowErrorMatchingInlineSnapshot(
@@ -170,96 +170,96 @@ describe('expandShorthandExtensionParameters', () => {
it('supports null value', () => {
// this is the result of typing:
- // - app/router:
+ // - app/root:
// The missing value is interpreted as null by the yaml parser so we deal with that
- expect(run({ 'app/router': null })).toEqual({
- id: 'app/router',
+ expect(run({ 'app/root': null })).toEqual({
+ id: 'app/root',
disabled: false,
});
});
it('supports boolean value', () => {
- expect(run({ 'app/router': true })).toEqual({
- id: 'app/router',
+ expect(run({ 'app/root': true })).toEqual({
+ id: 'app/root',
disabled: false,
});
- expect(run({ 'app/router': false })).toEqual({
- id: 'app/router',
+ expect(run({ 'app/root': false })).toEqual({
+ id: 'app/root',
disabled: true,
});
});
it('should not support string values', () => {
expect(() =>
- run({ 'app/router': 'example-package#MyRouter' }),
+ run({ 'app/root': 'example-package#MyRouter' }),
).toThrowErrorMatchingInlineSnapshot(
- `"Invalid extension configuration at app.extensions[1][app/router], value must be a boolean or object"`,
+ `"Invalid extension configuration at app.extensions[1][app/root], value must be a boolean or object"`,
);
});
it('supports object id only in the key', () => {
expect(() =>
- run({ 'app/router': { id: 'some.id' } }),
+ run({ 'app/root': { id: 'some.id' } }),
).toThrowErrorMatchingInlineSnapshot(
- `"Invalid extension configuration at app.extensions[1][app/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`,
+ `"Invalid extension configuration at app.extensions[1][app/root].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`,
);
});
it('supports object attachTo', () => {
expect(
run({
- 'app/router': { attachTo: { id: 'other.root', input: 'inputs' } },
+ 'app/root': { attachTo: { id: 'other.root', input: 'inputs' } },
}),
).toEqual({
- id: 'app/router',
+ id: 'app/root',
attachTo: { id: 'other.root', input: 'inputs' },
});
expect(() =>
run({
- 'app/router': {
+ 'app/root': {
id: 'other-id',
},
}),
).toThrowErrorMatchingInlineSnapshot(
- `"Invalid extension configuration at app.extensions[1][app/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`,
+ `"Invalid extension configuration at app.extensions[1][app/root].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`,
);
});
it('supports object disabled', () => {
- expect(run({ 'app/router': { disabled: true } })).toEqual({
- id: 'app/router',
+ expect(run({ 'app/root': { disabled: true } })).toEqual({
+ id: 'app/root',
disabled: true,
});
- expect(run({ 'app/router': { disabled: false } })).toEqual({
- id: 'app/router',
+ expect(run({ 'app/root': { disabled: false } })).toEqual({
+ id: 'app/root',
disabled: false,
});
expect(() =>
- run({ 'app/router': { disabled: 0 } }),
+ run({ 'app/root': { disabled: 0 } }),
).toThrowErrorMatchingInlineSnapshot(
- `"Invalid extension configuration at app.extensions[1][app/router].disabled, must be a boolean"`,
+ `"Invalid extension configuration at app.extensions[1][app/root].disabled, must be a boolean"`,
);
});
it('supports object config', () => {
- expect(
- run({ 'app/router': { config: { disableRedirects: true } } }),
- ).toEqual({
- id: 'app/router',
- config: { disableRedirects: true },
- });
+ expect(run({ 'app/root': { config: { disableRedirects: true } } })).toEqual(
+ {
+ id: 'app/root',
+ config: { disableRedirects: true },
+ },
+ );
expect(() =>
- run({ 'app/router': { config: 0 } }),
+ run({ 'app/root': { config: 0 } }),
).toThrowErrorMatchingInlineSnapshot(
- `"Invalid extension configuration at app.extensions[1][app/router].config, must be an object"`,
+ `"Invalid extension configuration at app.extensions[1][app/root].config, must be an object"`,
);
});
it('rejects unknown object keys', () => {
expect(() =>
- run({ 'app/router': { foo: { settings: true } } }),
+ run({ 'app/root': { foo: { settings: true } } }),
).toThrowErrorMatchingInlineSnapshot(
- `"Invalid extension configuration at app.extensions[1][app/router].foo, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`,
+ `"Invalid extension configuration at app.extensions[1][app/root].foo, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`,
);
});
});
diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx
index d5a206e7fb..e6ddc03e38 100644
--- a/packages/frontend-app-api/src/wiring/createApp.test.tsx
+++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx
@@ -194,7 +194,7 @@ describe('createApp', () => {
extensions: [
createExtension({
namespace: 'app',
- name: 'router',
+ name: 'root',
attachTo: { id: 'app', input: 'root' },
disabled: true,
output: {},
@@ -244,7 +244,7 @@ describe('createApp', () => {
expect(String(tree.root)).toMatchInlineSnapshot(`
"
root [
-
+
children [
content [
@@ -259,7 +259,7 @@ describe('createApp', () => {
]
]
-
+
]
components [
diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx
index 09a7034ffb..b25bad03bc 100644
--- a/packages/frontend-app-api/src/wiring/createApp.tsx
+++ b/packages/frontend-app-api/src/wiring/createApp.tsx
@@ -32,10 +32,10 @@ import {
RouteRef,
useRouteRef,
} from '@backstage/frontend-plugin-api';
-import { Core } from '../extensions/Core';
-import { CoreRoutes } from '../extensions/CoreRoutes';
-import { CoreLayout } from '../extensions/CoreLayout';
-import { CoreNav } from '../extensions/CoreNav';
+import { App } from '../extensions/App';
+import { AppRoutes } from '../extensions/AppRoutes';
+import { AppLayout } from '../extensions/AppLayout';
+import { AppNav } from '../extensions/AppNav';
import {
AnyApiFactory,
ApiHolder,
@@ -95,7 +95,7 @@ import {
} from '../extensions/components';
import { AppNode } from '@backstage/frontend-plugin-api';
import { InternalAppContext } from './InternalAppContext';
-import { CoreRouter } from '../extensions/CoreRouter';
+import { AppRoot } from '../extensions/AppRoot';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiring/createPlugin';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
@@ -106,11 +106,11 @@ import { stringifyError } from '@backstage/errors';
const DefaultApis = defaultApis.map(factory => createApiExtension({ factory }));
export const builtinExtensions = [
- Core,
- CoreRouter,
- CoreRoutes,
- CoreNav,
- CoreLayout,
+ App,
+ AppRoot,
+ AppRoutes,
+ AppNav,
+ AppLayout,
DefaultProgressComponent,
DefaultErrorBoundaryComponent,
DefaultNotFoundErrorPageComponent,
@@ -371,7 +371,7 @@ export function createSpecializedApp(options?: {
);
const rootEl = tree.root.instance!.getData(coreExtensionData.reactElement);
- const App = () => (
+ const AppComponent = () => (
@@ -387,7 +387,7 @@ export function createSpecializedApp(options?: {
return {
createRoot() {
- return ;
+ return ;
},
};
}
diff --git a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx
index 543a5447ad..b525cc3a7b 100644
--- a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx
+++ b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx
@@ -50,7 +50,7 @@ export function createSignInPageExtension<
kind: 'sign-in-page',
namespace: options?.namespace,
name: options?.name,
- attachTo: options.attachTo ?? { id: 'app/router', input: 'signInPage' },
+ attachTo: options.attachTo ?? { id: 'app/root', input: 'signInPage' },
configSchema: options.configSchema,
inputs: options.inputs,
disabled: options.disabled,
diff --git a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts
index cb02048bdc..d2f78122d3 100644
--- a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts
+++ b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts
@@ -150,7 +150,7 @@ describe('createPlugin', () => {
await renderWithEffects(
createTestAppRoot({
features: [plugin],
- config: { app: { extensions: [{ 'app/router': false }] } },
+ config: { app: { extensions: [{ 'app/root': false }] } },
}),
);
@@ -172,7 +172,7 @@ describe('createPlugin', () => {
config: {
app: {
extensions: [
- { 'app/router': false },
+ { 'app/root': false },
{
'test/2': {
config: { name: 'extension-2-renamed' },
@@ -210,7 +210,7 @@ describe('createPlugin', () => {
features: [plugin],
config: {
app: {
- extensions: [{ 'app/router': false }],
+ extensions: [{ 'app/root': false }],
},
},
}),
diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx
index aae2e5ed32..1a4ebbac48 100644
--- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx
+++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx
@@ -151,7 +151,7 @@ const AuthenticationProvider = (props: {
const TestCoreRouterExtension = createExtension({
namespace: 'app',
- name: 'router',
+ name: 'root',
attachTo: { id: 'app', input: 'root' },
inputs: {
signInPage: createExtensionInput(