diff --git a/website/astro.config.mjs b/website/astro.config.mjs index 84a89b33..89bffbc9 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -15,26 +15,32 @@ 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('/')) { - const hrefWithTrailingSlash = url.href.endsWith('/') ? url.href : url.href + '/'; - return baseNoTrailing + hrefWithTrailingSlash; - } + let newHref = baseNoTrailing; if (url.href.startsWith('#')) { - const absoluteUrl = `${baseNoTrailing}/${path}/${url.href}`; - return absoluteUrl; + // 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; } - // console.log(url.href + ' -> ', absoluteUrl); - return; + // console.log(url.href + ' -> ', newHref); + return newHref; })(tree); }; } @@ -44,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 2aa6acfe..ab18500f 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 4cee4282..6447d9d6 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; ---