From 41436ccb74a46c2155041d69b1b5e598e6c24bcc Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 15 Mar 2025 00:42:09 +0100 Subject: [PATCH 1/2] application.js: allow for relative URLs When running Hugo with relative URLs, as is the case when a developer runs `hugo` in a regular checkout of this repository, there is no `https://` prefix, and therefore the current logic failed. Fix this logic, and while at it, simplify the preceding code a bit. Note that this logic needs further adjustment, then, for importing the `pagefind.js` library: This `import`, if relative, is relative to the location of `application.js` (which is not the case where `baseURLPrefix` is used to set `href` and `src` attributes, which are relative to the top-level directory of the site). This _happened_ to work before because the bug was hidden by the bug where `baseURLPrefix` was not adjusted correctly for `HUGO_RELATIVEURLS=true`. Signed-off-by: Johannes Schindelin --- assets/js/application.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/assets/js/application.js b/assets/js/application.js index 0b7f0f54e9..5611b46962 100644 --- a/assets/js/application.js +++ b/assets/js/application.js @@ -21,10 +21,12 @@ popped = 'state' in window.history; initialURL = location.href; const baseURLPrefix = (() => { - const scripts = document.getElementsByTagName('script'); - const index = scripts.length - 1; - const thisScript = scripts[index]; - return thisScript.src.replace(/^.*:\/\/[^/]*(.*\/)(assets|js)\/[^/]+.js(\?.*)?$/, '$1'); + const thisScriptSrc = + Array.from(document.getElementsByTagName('script')) + .pop() + .getAttribute('src'); + return thisScriptSrc + .replace(/^(?:[a-z]*:\/\/[^/]*)?(.*\/)(assets|js)\/[^/]+.js(\?.*)?$/, '$1'); })(); $(document).ready(function() { @@ -338,7 +340,15 @@ var Search = { return; } (async () => { - Search.pagefind = await import(`${baseURLPrefix}pagefind/pagefind.js`); + const pagefindURL = + `${baseURLPrefix}pagefind/pagefind.js` + // adjust the `baseURLPrefix` if it is relative: the `import` + // is relative to the _script URL_ here, which is in /js/. + // That is different from other uses of `baseURLPrefix`, which + // replace `href` and `src` attributes which are relative to the + // page itself that is outside of /js/. + .replace(/^\.\//, '../') + Search.pagefind = await import(pagefindURL); const options = { ranking: { pageLength: 0.1, // boost longer pages From 9b59a3062bad3b4a9e77d6db0ef263ce386f8cd1 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 15 Mar 2025 13:30:48 +0100 Subject: [PATCH 2/2] script/serve-public.js(404): handle relative URLs When building the site with `HUGO_RELATIVEURLS=true` (which is the default when building locally), the `404.html` page rightfully assumes that its resources, such as images, can be found via relative URLs like `./images/favicon.ico`. That leads to a problem when the `serve-public.js` script wants to Use it in case it does not have certain file that is in a subdirectory. For example, when a developer directs their web browser to http://localhost:5000/docs/git-undo, the result will be the 4O4 page, but it will be unstyled because it looks for the CSS and the wrong location. The solution is to specify the base URL explictly in the served 404 page. In this instance it is easy because we know exactly that this script will serve the site via http://localhost:5000/ and therefore the base url is simply the `/`. Signed-off-by: Johannes Schindelin --- script/serve-public.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/script/serve-public.js b/script/serve-public.js index 94679800f9..ea8fddac3e 100755 --- a/script/serve-public.js +++ b/script/serve-public.js @@ -49,7 +49,11 @@ const handler = (request, response) => { } catch(e) { console.log(`Could not read ${filename}`); response.writeHead(404, {'Content-Type': 'text/html'}); - fs.createReadStream(path.join(basePath, '404.html')).pipe(response); + // insert to fix styling + const html = fs.readFileSync(path.join(basePath, '404.html'), 'utf-8') + .replace(//, '\n ') + response.write(html) + response.end() return; } };