Skip to content

Commit 7f20e49

Browse files
committed
fix: redirect /docs/<latestVersion>/* to unprefixed /docs/* paths
Signed-off-by: chathuranga95 <siriwardhanachathuranga@gmail.com>
1 parent ea25f9b commit 7f20e49

3 files changed

Lines changed: 82 additions & 4 deletions

File tree

docusaurus.config.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { themes as prismThemes } from 'prism-react-renderer';
22
import type { Config } from '@docusaurus/types';
33
import type * as Preset from '@docusaurus/preset-classic';
44
import path from 'path';
5+
import versions from './versions.json';
6+
7+
// Latest docs version (Docusaurus prepends new versions to versions.json).
8+
const latestVersion = versions[0];
59

610
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
711

@@ -54,6 +58,36 @@ const config: Config = {
5458
'./plugins/docusaurus-plugin-markdown-export',
5559
'./plugins/docusaurus-plugin-llms-txt',
5660
'./plugins/docusaurus-plugin-docs-scripts',
61+
[
62+
'@docusaurus/plugin-client-redirects',
63+
{
64+
// Docusaurus serves the latest docs version unprefixed (/docs/foo),
65+
// so /docs/<latestVersion>/foo 404s. For each real /docs/foo page,
66+
// register /docs/<latestVersion>/foo as an alias that redirects to it.
67+
// Reads latestVersion from versions.json, so no manual updates per release.
68+
createRedirects(existingPath: string) {
69+
const isDocsPath =
70+
existingPath === '/docs' || existingPath.startsWith('/docs/');
71+
const isVersionedDocsPath = versions.some((v) => {
72+
const versionedDocsPath = `/docs/${v}`;
73+
return (
74+
existingPath === versionedDocsPath ||
75+
existingPath.startsWith(`${versionedDocsPath}/`)
76+
);
77+
});
78+
const isLatestDocsPath =
79+
isDocsPath && !isVersionedDocsPath;
80+
81+
if (!isLatestDocsPath) return undefined;
82+
83+
const aliasWithLatestVersionPrefix = existingPath.replace(
84+
/^\/docs/,
85+
`/docs/${latestVersion}`,
86+
);
87+
return [aliasWithLatestVersionPrefix];
88+
},
89+
},
90+
],
5791
function webpackPolyfillsPlugin() {
5892
const webpack = require('webpack');
5993
return {
@@ -135,7 +169,25 @@ const config: Config = {
135169
} satisfies Preset.Options,
136170
],
137171
],
138-
172+
173+
headTags: [
174+
{
175+
tagName: 'script',
176+
attributes: {},
177+
innerHTML: `
178+
(function () {
179+
var latestDocsVersionPath = '/docs/${latestVersion}';
180+
var pathname = window.location.pathname;
181+
var normalizedPathname =
182+
pathname !== '/' && pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
183+
184+
if (normalizedPathname === latestDocsVersionPath) {
185+
window.location.replace('/docs/' + window.location.search + window.location.hash);
186+
}
187+
})();
188+
`,
189+
},
190+
],
139191

140192
clientModules: [
141193
path.join(__dirname, 'src/clientModules/gtagGuard.ts'),

package-lock.json

Lines changed: 28 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"dependencies": {
2121
"@docsearch/docusaurus-adapter": "^4.6.3",
2222
"@docusaurus/core": "^3.9.2",
23+
"@docusaurus/plugin-client-redirects": "^3.9.2",
2324
"@docusaurus/preset-classic": "^3.9.2",
2425
"@docusaurus/theme-mermaid": "^3.9.2",
2526
"@mdx-js/react": "^3.1.1",

0 commit comments

Comments
 (0)