From 807d2a72218823c7cf49d11bcec06da7e2d90a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marina=20A=C3=ADsa?= Date: Fri, 3 Oct 2025 18:03:22 +0200 Subject: [PATCH 1/4] Split routes into fallbackRoutes and pagesRoutes We want to split the routes into fallbackRoutes and pageRoutes to have more flexibility into how to organize the routes in our app. --- src/routes.js | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/routes.js b/src/routes.js index 0c928ce37..11343bed5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -16,7 +16,20 @@ import { import ServerError from 'theme/views/ServerError.vue'; import NotFound from 'theme/views/NotFound.vue'; -export default [ +export const fallbackRoutes = [ + { + path: '*', + name: notFoundRouteName, + component: NotFound, + }, + { + path: '*', // purposefully unreachable without a forced navigation + name: serverErrorRouteName, + component: ServerError, + }, +]; + +export const pagesRoutes = [ { path: '/tutorials/:id', name: 'tutorials-overview', @@ -38,14 +51,9 @@ export default [ /* webpackChunkName: "documentation-topic" */ 'theme/views/DocumentationTopic.vue' ), }, - { - path: '*', - name: notFoundRouteName, - component: NotFound, - }, - { - path: '*', // purposefully unreachable without a forced navigation - name: serverErrorRouteName, - component: ServerError, - }, +]; + +export default [ + ...pagesRoutes, + ...fallbackRoutes, ]; From 162bbdf7022992cb8048979a3be2a5594d044265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marina=20A=C3=ADsa?= Date: Fri, 3 Oct 2025 18:49:49 +0200 Subject: [PATCH 2/4] Add translated routes between pageRoutes and fallbackRoutes The order for our routes should be: - page routes - localized page routes - fallback routes This is important because otherwise the request for localized routes will fall into the fallback routes. Before, the routes were: [ { "path": "/tutorials/:id", "name": "tutorials-overview" }, { "path": "/tutorials/:id/*", "name": "topic" }, { "path": "/documentation*", "name": "documentation-topic" }, { "path": "*", "name": "not-found", "component": {...} }, { "path": "*", "name": "server-error", "component": {...} }, { "path": "/:locale?/tutorials/:id", "name": "tutorials-overview-locale" }, { "path": "/:locale?/tutorials/:id/*", "name": "topic-locale" }, { "path": "/:locale?/documentation*", "name": "documentation-topic-locale" } ] Now they are: [ { "path": "/tutorials/:id", "name": "tutorials-overview" }, { "path": "/tutorials/:id/*", "name": "topic" }, { "path": "/documentation*", "name": "documentation-topic" }, { "path": "/:locale?/tutorials/:id", "name": "tutorials-overview-locale" }, { "path": "/:locale?/tutorials/:id/*", "name": "topic-locale" }, { "path": "/:locale?/documentation*", "name": "documentation-topic-locale" }, { "path": "*", "name": "not-found", "component": {...} }, { "path": "*", "name": "server-error", "component": {...} } ] --- src/setup-utils/SwiftDocCRenderRouter.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/setup-utils/SwiftDocCRenderRouter.js b/src/setup-utils/SwiftDocCRenderRouter.js index 87ba2a4ac..f484005ab 100644 --- a/src/setup-utils/SwiftDocCRenderRouter.js +++ b/src/setup-utils/SwiftDocCRenderRouter.js @@ -18,16 +18,17 @@ import { restoreScrollOnReload, scrollBehavior, } from 'docc-render/utils/router-utils'; -import routes from 'docc-render/routes'; +import routes, { pagesRoutes, fallbackRoutes } from 'docc-render/routes'; import { baseUrl } from 'docc-render/utils/theme-settings'; import { addPrefixedRoutes } from 'docc-render/utils/route-utils'; const defaultRoutes = [ - ...routes, + ...pagesRoutes, ...addPrefixedRoutes(routes, [ notFoundRouteName, serverErrorRouteName, ]), + ...fallbackRoutes, ]; export default function createRouterInstance(routerConfig = {}) { From a61232be2d6e397e185212e9728412caa5f50dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marina=20A=C3=ADsa?= Date: Fri, 3 Oct 2025 19:04:08 +0200 Subject: [PATCH 3/4] Locale fallback pages Pages like Not Found or Server error pages should also be localized, so we need to add them into the router's paths. Before, the routes were: [ { "path": "/tutorials/:id", "name": "tutorials-overview" }, { "path": "/tutorials/:id/*", "name": "topic" }, { "path": "/documentation*", "name": "documentation-topic" }, { "path": "/:locale?/tutorials/:id", "name": "tutorials-overview-locale" }, { "path": "/:locale?/tutorials/:id/*", "name": "topic-locale" }, { "path": "/:locale?/documentation*", "name": "documentation-topic-locale" }, { "path": "*", "name": "not-found", "component": {...} }, { "path": "*", "name": "server-error", "component": {...} } ] Now they are: [ { "path": "/tutorials/:id", "name": "tutorials-overview" }, { "path": "/tutorials/:id/*", "name": "topic" }, { "path": "/documentation*", "name": "documentation-topic" }, { "path": "/:locale?/tutorials/:id", "name": "tutorials-overview-locale" }, { "path": "/:locale?/tutorials/:id/*", "name": "topic-locale" }, { "path": "/:locale?/documentation*", "name": "documentation-topic-locale" }, { "path": "/:locale?/*", "name": "not-found-locale", "component": {...} }, { "path": "/:locale?/*", "name": "server-error-locale", "component": {...} }, { "path": "*", "name": "not-found", "component": {...} }, { "path": "*", "name": "server-error", "component": {...} } ] --- src/components/ContentNode/Reference.vue | 2 +- src/setup-utils/SwiftDocCRenderRouter.js | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/components/ContentNode/Reference.vue b/src/components/ContentNode/Reference.vue index d9dbe19ae..b959691f9 100644 --- a/src/components/ContentNode/Reference.vue +++ b/src/components/ContentNode/Reference.vue @@ -70,7 +70,7 @@ export default { } = this.$router.resolve(url) || {}; // Resolved internal URLs don't have the "not found" route. - return name !== notFoundRouteName; + return !name.startsWith(notFoundRouteName); }, isSymbolReference() { return this.kind === 'symbol' && !this.hasInlineFormatting diff --git a/src/setup-utils/SwiftDocCRenderRouter.js b/src/setup-utils/SwiftDocCRenderRouter.js index f484005ab..b379a4c52 100644 --- a/src/setup-utils/SwiftDocCRenderRouter.js +++ b/src/setup-utils/SwiftDocCRenderRouter.js @@ -9,10 +9,6 @@ */ import Router from 'vue-router'; -import { - notFoundRouteName, - serverErrorRouteName, -} from 'docc-render/constants/router'; import { saveScrollOnReload, restoreScrollOnReload, @@ -24,10 +20,7 @@ import { addPrefixedRoutes } from 'docc-render/utils/route-utils'; const defaultRoutes = [ ...pagesRoutes, - ...addPrefixedRoutes(routes, [ - notFoundRouteName, - serverErrorRouteName, - ]), + ...addPrefixedRoutes(routes), ...fallbackRoutes, ]; From 8a0579a963a2da87c1c5db291589ff054da04b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marina=20A=C3=ADsa?= Date: Tue, 7 Oct 2025 17:59:21 +0100 Subject: [PATCH 4/4] Remove repeated routes Since the param locale is optional: `/:locale?/` we were repeating the pages routes in the app. Vue Router requires explicit catch-all routes for not-found handling so we need to keep the fallback routes too. [1] The new order for our routes should be: - localized page routes - localized fallback routes - fallback routes Before, the routes were: [ { "path": "/tutorials/:id", "name": "tutorials-overview" }, { "path": "/tutorials/:id/*", "name": "topic" }, { "path": "/documentation*", "name": "documentation-topic" }, { "path": "/:locale?/tutorials/:id", "name": "tutorials-overview-locale" }, { "path": "/:locale?/tutorials/:id/*", "name": "topic-locale" }, { "path": "/:locale?/documentation*", "name": "documentation-topic-locale" }, { "path": "/:locale?/*", "name": "not-found-locale", "component": {...} }, { "path": "/:locale?/*", "name": "server-error-locale", "component": {...} }, { "path": "*", "name": "not-found", "component": {...} }, { "path": "*", "name": "server-error", "component": {...} } ] Now they are: [ { "path": "/:locale?/tutorials/:id", "name": "tutorials-overview-locale" }, { "path": "/:locale?/tutorials/:id/*", "name": "topic-locale" }, { "path": "/:locale?/documentation*", "name": "documentation-topic-locale" }, { "path": "/:locale?/*", "name": "not-found-locale", "component": {...} }, { "path": "/:locale?/*", "name": "server-error-locale", "component": {...} }, { "path": "*", "name": "not-found", "component": {...} }, { "path": "*", "name": "server-error", "component": {...} }, ] [1] https://v3.router.vuejs.org/guide/essentials/dynamic-matching.html#catch-all-404-not-found-route --- src/setup-utils/SwiftDocCRenderRouter.js | 3 +-- tests/unit/setup-utils/SwiftDocCRenderRouter.spec.js | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/setup-utils/SwiftDocCRenderRouter.js b/src/setup-utils/SwiftDocCRenderRouter.js index b379a4c52..26a70308d 100644 --- a/src/setup-utils/SwiftDocCRenderRouter.js +++ b/src/setup-utils/SwiftDocCRenderRouter.js @@ -14,12 +14,11 @@ import { restoreScrollOnReload, scrollBehavior, } from 'docc-render/utils/router-utils'; -import routes, { pagesRoutes, fallbackRoutes } from 'docc-render/routes'; +import routes, { fallbackRoutes } from 'docc-render/routes'; import { baseUrl } from 'docc-render/utils/theme-settings'; import { addPrefixedRoutes } from 'docc-render/utils/route-utils'; const defaultRoutes = [ - ...pagesRoutes, ...addPrefixedRoutes(routes), ...fallbackRoutes, ]; diff --git a/tests/unit/setup-utils/SwiftDocCRenderRouter.spec.js b/tests/unit/setup-utils/SwiftDocCRenderRouter.spec.js index 5d6df4b34..ecbc0abf1 100644 --- a/tests/unit/setup-utils/SwiftDocCRenderRouter.spec.js +++ b/tests/unit/setup-utils/SwiftDocCRenderRouter.spec.js @@ -118,8 +118,8 @@ describe('SwiftDocCRenderRouter', () => { const resolve = path => router.resolve(path).route; - it('resolves paths to the "tutorials-overview" route', () => { - const route = 'tutorials-overview'; + it('resolves paths to the "tutorials-overview-locale" route', () => { + const route = 'tutorials-overview-locale'; expect(resolve('/tutorials/foo').name).toBe(route); expect(resolve('/tutorials/bar').name).toBe(route); @@ -140,8 +140,8 @@ describe('SwiftDocCRenderRouter', () => { expect(resolve('/zh-CN/tutorials/foo/bar').name).not.toBe(route); }); - it('resolves paths to the "topic" route', () => { - const route = 'topic'; + it('resolves paths to the "topic-locale" route', () => { + const route = 'topic-locale'; expect(resolve('/tutorials/foo/bar').name).toBe(route); expect(resolve('/tutorials/foobar/baz').name).toBe(route); expect(resolve('/tutorials/documentation/foo').name).toBe(route); @@ -163,8 +163,8 @@ describe('SwiftDocCRenderRouter', () => { }); }); - it('resolves paths to the "documentation-topic" route', () => { - const route = 'documentation-topic'; + it('resolves paths to the "documentation-topic-locale" route', () => { + const route = 'documentation-topic-locale'; expect(resolve('/documentation/foo').name).toBe(route); expect(resolve('/documentation/bar').name).toBe(route);