diff --git a/packages/docusaurus/src/server/htmlTags.ts b/packages/docusaurus/src/server/htmlTags.ts
index e61f946804..d6587a91ac 100644
--- a/packages/docusaurus/src/server/htmlTags.ts
+++ b/packages/docusaurus/src/server/htmlTags.ts
@@ -36,16 +36,24 @@ function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject {
}
}
+function absoluteToRelativeTagAttribute(name: string, value: string): string {
+ if ((name === 'src' || name === 'href') && value.startsWith('/')) {
+ return `.${value}`; // TODO would only work for homepage
+ }
+ return value;
+}
+
function htmlTagObjectToString(tag: unknown): string {
assertIsHtmlTagObject(tag);
const isVoidTag = (voidHtmlTags as string[]).includes(tag.tagName);
const tagAttributes = tag.attributes ?? {};
const attributes = Object.keys(tagAttributes)
.map((attr) => {
- const value = tagAttributes[attr]!;
+ let value = tagAttributes[attr]!;
if (typeof value === 'boolean') {
return value ? attr : undefined;
}
+ value = absoluteToRelativeTagAttribute(attr, value);
return `${attr}="${escapeHTML(value)}"`;
})
.filter((str): str is string => Boolean(str));
diff --git a/packages/docusaurus/src/ssg.ts b/packages/docusaurus/src/ssg.ts
index a1e6d4e9ce..76dfbdade4 100644
--- a/packages/docusaurus/src/ssg.ts
+++ b/packages/docusaurus/src/ssg.ts
@@ -182,6 +182,7 @@ async function generateStaticFile({
});
// This renders the full page HTML, including head tags...
const fullPageHtml = renderSSRTemplate({
+ pathname,
params,
result,
});
diff --git a/packages/docusaurus/src/templates/templates.ts b/packages/docusaurus/src/templates/templates.ts
index 24c5fb1005..2765baa47e 100644
--- a/packages/docusaurus/src/templates/templates.ts
+++ b/packages/docusaurus/src/templates/templates.ts
@@ -63,9 +63,11 @@ function getScriptsAndStylesheets({
}
export function renderSSRTemplate({
+ pathname,
params,
result,
}: {
+ pathname: string;
params: SSGParams;
result: AppRenderResult;
}): string {
@@ -96,9 +98,18 @@ export function renderSSRTemplate({
];
const metaAttributes = metaStrings.filter(Boolean);
+ const numberOfSlashes = pathname.match(/\//g)?.length ?? 0;
+
+ const local = true;
+
+ const localBaseUrl =
+ numberOfSlashes === 1 ? `./` : '../'.repeat(numberOfSlashes - 1);
+
+ // console.log({pathname, numberOfSlashes, baseUrl, finalBaseUrl, headTags});
+
const data: SSRTemplateData = {
appHtml,
- baseUrl,
+ baseUrl: local ? localBaseUrl : baseUrl,
htmlAttributes,
bodyAttributes,
headTags,
diff --git a/packages/docusaurus/src/webpack/base.ts b/packages/docusaurus/src/webpack/base.ts
index f7fcb238de..98c98f4570 100644
--- a/packages/docusaurus/src/webpack/base.ts
+++ b/packages/docusaurus/src/webpack/base.ts
@@ -112,7 +112,7 @@ export async function createBaseConfig({
chunkFilename: isProd
? 'assets/js/[name].[contenthash:8].js'
: '[name].js',
- publicPath: baseUrl,
+ publicPath: isServer ? baseUrl : 'auto',
hashFunction: 'xxhash64',
},
// Don't throw warning when asset created is over 250kb