diff --git a/_config/relative-links.js b/_config/relative-links.js new file mode 100644 index 0000000..ee6cd4a --- /dev/null +++ b/_config/relative-links.js @@ -0,0 +1,59 @@ +/** + * https://github.com/11ty/eleventy/discussions/2516#discussioncomment-11999750 + * + * Referring to HtmlBasePlugin.js + * + * This plugin tries to make all URLs in the HTML output relative to the page. + * + * Useful for: + * * browsing via file:// + * * gh-pages in subdirectory repo + * * unsure where in the directory structure the site will be hosted + * + * We're expecting the internal links to start with "/" + * + * todo? + * * option to include "index.html" for those directory links, for extra file:// compat + * + */ + +import path from "path"; + +export default function (eleventyConfig) { + // Apply to all HTML output in your project + eleventyConfig.htmlTransformer.addUrlTransform( + "html", + function makeUrlRelative(urlInMarkup) { + // Skip empty URLs, non-root-relative URLs, and dev server image transform URLs + if ( + !urlInMarkup + || !urlInMarkup.startsWith("/") + || urlInMarkup.startsWith("/.11ty/") + || urlInMarkup.startsWith("//") + ) { + return urlInMarkup; + } + + // Get base directory path (keep trailing slash for index pages) + const fromDir = this.url.endsWith("/") ? this.url : path.dirname(this.url); + + let relativePath = path.relative(fromDir, urlInMarkup); + + // Add ./ for same-directory references + if (!relativePath.startsWith(".")) { + relativePath = "./" + relativePath; + } + + // Preserve trailing slash from original URL + if (urlInMarkup.endsWith("/") && !relativePath.endsWith("/")) { + relativePath += "/"; + } + + // console.log(this.url, fromDir, urlInMarkup, relativePath); + return relativePath; + }, + { + priority: -1, // run last last (after PathToUrl) + }, + ); +} diff --git a/eleventy.config.js b/eleventy.config.js index 0b69b0e..9f66e9e 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -5,6 +5,7 @@ import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; import { JSDOM } from 'jsdom'; import { DateTime } from "luxon"; import markdownItAnchor from 'markdown-it-anchor'; +import relativeLinks from "./_config/relative-links.js"; /** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */ export default function(eleventyConfig) { @@ -47,6 +48,9 @@ export default function(eleventyConfig) { outputFunctionName: 'print', }); + // custom plugins + eleventyConfig.addPlugin(relativeLinks); + // Filters eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens