diff --git a/website/astro.config.mjs b/website/astro.config.mjs index f8fceaf76..89bffbc9d 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -13,24 +13,34 @@ import AstroPWA from '@vite-pwa/astro'; const site = `https://strudel.cc/`; // root url without a path const base = '/'; // base path of the strudel site +const baseNoTrailing = base.endsWith('/') ? base.slice(0, -1) : base; -// this rehype plugin converts relative anchor links to absolute ones -// it wokrs by prepending the absolute page path to anchor links -// example: #gain -> /learn/effects/#gain +// this rehype plugin fixes relative links +// it works by prepending the base + page path to anchor links +// and by prepending the base path to other relative links starting with / // this is necessary when using a base href like -// in this setup, relative anchor links will always link to base, instead of the current page -function absoluteAnchors() { +// examples with base as "mybase": +// #gain -> /mybase/learn/effects/#gain +// /some/page -> /mybase/some/page +function relativeURLFix() { return (tree, file) => { const chunks = file.history[0].split('/src/pages/'); // file.history[0] is the file path const path = chunks[chunks.length - 1].slice(0, -4); // only path inside src/pages, without .mdx return rehypeUrls((url) => { - if (!url.href.startsWith('#')) { + let newHref = baseNoTrailing; + if (url.href.startsWith('#')) { + // special case: a relative anchor link to the current page + newHref += `/${path}/${url.href}`; + } else if (url.href.startsWith('/')) { + // any other relative url starting with / + // NOTE: this does strip off serialized queries and fragments + newHref += url.pathname.endsWith('/') ? url.pathname : url.pathname + '/'; + } else { + // leave this URL alone return; } - const baseWithSlash = base.endsWith('/') ? base : base + '/'; - const absoluteUrl = baseWithSlash + path + url.href; - // console.log(url.href + ' -> ', absoluteUrl); - return absoluteUrl; + // console.log(url.href + ' -> ', newHref); + return newHref; })(tree); }; } @@ -40,7 +50,7 @@ const options = { remarkToc, // E.g. `remark-frontmatter` ], - rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'append' }], absoluteAnchors], + rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'append' }], relativeURLFix], }; // https://astro.build/config diff --git a/website/src/components/HeadCommon.astro b/website/src/components/HeadCommon.astro index 2aa6acfe4..ab18500f3 100644 --- a/website/src/components/HeadCommon.astro +++ b/website/src/components/HeadCommon.astro @@ -3,7 +3,7 @@ import { pwaInfo } from 'virtual:pwa-info'; import '../styles/index.css'; const { BASE_URL } = import.meta.env; -const base = BASE_URL; +const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; --- @@ -11,20 +11,20 @@ const base = BASE_URL; - + - - + + - + - + diff --git a/website/src/components/Header/Header.astro b/website/src/components/Header/Header.astro index 4cee42828..6447d9d63 100644 --- a/website/src/components/Header/Header.astro +++ b/website/src/components/Header/Header.astro @@ -16,6 +16,9 @@ const { currentPage } = Astro.props as Props; // const lang = getLanguageFromURL(currentPage); const langCode = 'en'; // getLanguageFromURL(currentPage); const sidebar = SIDEBAR[langCode]; + +const { BASE_URL } = import.meta.env; +const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; ---