- Stable
3.0.0
- Canary
3.0.1-alpha.1
Toggle Menu
1.93s
70.65s
HTML <base>
Added in v2.0.0
A build-time application of <base>
to HTML (without relying on <base>
) by modifying a[href]
, video[src]
, audio[src]
, source
, img[src]
, [srcset]
, and more.
- Read about HTML’s
<base>
element on MDN
If you want to deploy your project in a different directory without changing the content, Eleventy provides a Path Prefix feature to specify the target directory.
- via
--pathprefix
on the command line - or via
pathPrefix
object key in your configuration file return object
Historically, we then recommended to use the provided url
filter in your templates to transform any local URL with the path prefix. The downside of this method was that it required you to remember and opt-in every URL transformation in your content!
The New Way: HTML <base>
Plugin
With this new plugin, you no longer need to use the url
filter in your HTML content. This plugin adds an Eleventy Transform that will modify your HTML output and inject your Path Prefix in your template content.
- Behind the scenes, this plugin uses posthtml-urls and transforms
a[href]
,video[src]
,audio[src]
,source
,img[src]
,[srcset]
and a whole bunch more.
Why not use the <base>
HTML element?
You can, if you’d like! Some folks have found it to be a bit unreliable and edge-casey. This offers a build-time alternative.
Installation
Added in v2.0.0 This plugin is bundled with Eleventy 2.0 (no extra installation is required). It works with all template languages (via an Eleventy Transform) and some of the advanced usage filters require async-friendly template syntax (Nunjucks, Liquid, and JavaScript).
Open up your Eleventy config file (probably eleventy.config.js
) and use addPlugin
:
import { EleventyHtmlBasePlugin } from "@11ty/eleventy";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
}
module.exports = async function (eleventyConfig) {
const { EleventyHtmlBasePlugin } = await import("@11ty/eleventy");
eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
}
You’re only allowed one module.exports
in your configuration file, so make sure you only copy the require
and the addPlugin
lines above!
Expand for full options list
import { EleventyHtmlBasePlugin } from "@11ty/eleventy";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(EleventyHtmlBasePlugin, {
// The base URL: defaults to Path Prefix
baseHref: eleventyConfig.pathPrefix,
// But you could use a full URL here too:
// baseHref: "http://example.com/"
// Comma separated list of output file extensions to apply
// our transform to. Use `false` to opt-out of the transform.
extensions: "html",
});
}
module.exports = async function (eleventyConfig) {
const { EleventyHtmlBasePlugin } = await import("@11ty/eleventy");
eleventyConfig.addPlugin(EleventyHtmlBasePlugin, {
// The base URL: defaults to Path Prefix
baseHref: eleventyConfig.pathPrefix,
// But you could use a full URL here too:
// baseHref: "http://example.com/"
// Comma separated list of output file extensions to apply
// our transform to. Use `false` to opt-out of the transform.
extensions: "html",
});
}
Usage
For templates that output *.html
files, you don’t need to do anything else. The HTML plugin will automatically apply the Path Prefix to URLs in any html
file in your output directory.
Advanced Usage
This plugin also provides new filters for you to use these transformations manually. This is useful when you want to use the same functionality but the URL you want to transform is not in one of the HTML elements that get automatically transformed (like an HTML comment <!-- Current page: {{ page.url }} -->
).
htmlBaseUrl
Transform a single URL string using the base.
With path prefix set to "/pathprefix/"
:
{{ "/test/" | htmlBaseUrl }}
=> "/pathprefix/test/"
Relative paths are ignored:
{{ "test/" | htmlBaseUrl }}
=> "test/"
{{ "../test/" | htmlBaseUrl }}
=> "../test/"
Absolute URLs are ignored:
{{ "http://example.com/" | htmlBaseUrl }}
=> "http://example.com/"
With path prefix set to "/pathprefix/"
:
{{ "/test/" | htmlBaseUrl }}
=> "/pathprefix/test/"
Relative paths are ignored:
{{ "test/" | htmlBaseUrl }}
=> "test/"
{{ "../test/" | htmlBaseUrl }}
=> "../test/"
Absolute URLs are ignored:
{{ "http://example.com/" | htmlBaseUrl }}
=> "http://example.com/"
With path prefix set to "/pathprefix/"
:
export default function () {
return `
${this.htmlBaseUrl("/test/")}
=> "/pathprefix/test/"
Relative paths are ignored:
${this.htmlBaseUrl("test/")}
=> "test/"
${this.htmlBaseUrl("../test/")}
=> "../test/"
Absolute URLs are ignored:
${this.htmlBaseUrl("http://example.com/")}
=> "http://example.com/"
`;
};
With path prefix set to "/pathprefix/"
:
module.exports = function () {
return `
${this.htmlBaseUrl("/test/")}
=> "/pathprefix/test/"
Relative paths are ignored:
${this.htmlBaseUrl("test/")}
=> "test/"
${this.htmlBaseUrl("../test/")}
=> "../test/"
Absolute URLs are ignored:
${this.htmlBaseUrl("http://example.com/")}
=> "http://example.com/"
`;
};
You can override the baseHref
option by passing another argument to the filter with your one-off base value. Note that when you use a full URL as your base href, relative paths are no longer ignored—they are modified using the current page’s URL:
With path prefix set to "/pathprefix/"
:
{{ "/test/" | htmlBaseUrl: "http://example.com/" }}
=> "http://example.com/pathprefix/test/"
Relative urls are resolved using the current page’s url.
For example, on a page with URL `/my-template/`:
{{ "test/" | htmlBaseUrl: "http://example.com/" }}
=> "http://example.com/pathprefix/my-template/test/"
Absolute URLs are still ignored:
{{ "http://11ty.dev/" | htmlBaseUrl: "http://example.com/" }}
=> "http://11ty.dev/"
With path prefix set to "/pathprefix/"
:
{{ "/test/" | htmlBaseUrl("http://example.com/") }}
=> "http://example.com/pathprefix/test/"
Relative urls are resolved using the current page’s url.
For example, on a page with URL `/my-template/`:
{{ "test/" | htmlBaseUrl("http://example.com/") }}
=> "http://example.com/pathprefix/my-template/test/"
Absolute URLs are still ignored:
{{ "http://11ty.dev/" | htmlBaseUrl("http://example.com/") }}
=> "http://11ty.dev/"
With path prefix set to "/pathprefix/"
:
export default function () {
return (
`
${this.htmlBaseUrl("/test/", "http://example.com/")}
=> "http://example.com/pathprefix/test/"
Relative urls are resolved using the current page’s url.
For example, on a page with URL ` /
my -
template /
`:
${this.htmlBaseUrl("test/", "http://example.com/")}
=> "http://example.com/pathprefix/my-template/test/"
Absolute URLs are still ignored:
${this.htmlBaseUrl("http://11ty.dev/", "http://example.com/")}
=> "http://11ty.dev/"`
);
};
With path prefix set to "/pathprefix/"
:
module.exports = function () {
return (
`
${this.htmlBaseUrl("/test/", "http://example.com/")}
=> "http://example.com/pathprefix/test/"
Relative urls are resolved using the current page’s url.
For example, on a page with URL ` /
my -
template /
`:
${this.htmlBaseUrl("test/", "http://example.com/")}
=> "http://example.com/pathprefix/my-template/test/"
Absolute URLs are still ignored:
${this.htmlBaseUrl("http://11ty.dev/", "http://example.com/")}
=> "http://11ty.dev/"`
);
};
transformWithHtmlBase
Transform a block of HTML with posthtml. Applies the above htmlBaseUrl
filter to each applicable URL in an HTML block (so the URL transformation rules are the same). Requires an async-friendly template language.
We use this in the RSS plugin to change your content to be absolute URLs for broadest compatibility with various RSS feed readers.
With path prefix set to "/pathprefix/"
:
{{ '<a href="/test/">Link</a>' | transformWithHtmlBase }}
=> '<a href="/pathprefix/test/">Link</a>'
{{ '<a href="/test/">Link</a>' | transformWithHtmlBase: "http://example.com/" }}
=> '<a href="http://example.com/pathprefix/test/">Link</a>'
Resolving relative URLs (with path prefix still at "/pathprefix/"
):
On a page with URL `/my-template/`:
{{ '<a href="test/">Link</a>' | transformWithHtmlBase: "http://example.com/" }}
=> '<a href="http://example.com/pathprefix/my-template/test/">Link</a>'
Override the page URL:
{{ '<a href="test/">Link</a>' | transformWithHtmlBase: "http://example.com/", "/my-other-template/" }}
=> '<a href="http://example.com/pathprefix/my-other-template/test/">Link</a>'
With path prefix set to "/pathprefix/"
:
{{ '<a href="/test/">Link</a>' | transformWithHtmlBase }}
=> '<a href="/pathprefix/test/">Link</a>'
{{ '<a href="/test/">Link</a>' | transformWithHtmlBase("http://example.com/") }}
=> '<a href="http://example.com/pathprefix/test/">Link</a>'
Resolving relative URLs (with path prefix still at "/pathprefix/"
):
On a page with URL `/my-template/`:
{{ '<a href="test/">Link</a>' | transformWithHtmlBase("http://example.com/") }}
=> '<a href="http://example.com/pathprefix/my-template/test/">Link</a>'
Override the page URL:
{{ '<a href="test/">Link</a>' | transformWithHtmlBase("http://example.com/", "/my-other-template/") }}
=> '<a href="http://example.com/pathprefix/my-other-template/test/">Link</a>'
With path prefix set to "/pathprefix/"
:
export default async function () {
return `
${await this.transformWithHtmlBase(`<a href="/test/">Link</a>`)}
=> '<a href="/pathprefix/test/">Link</a>'
${await this.transformWithHtmlBase(
`<a href="/test/">Link</a>`,
"http://example.com/"
)}
=> '<a href="http://example.com/pathprefix/test/">Link</a>'`;
};
Resolving relative URLs (with path prefix still at "/pathprefix/"
):
export default async function () {
return `
On a page with URL "/my-template/":
${await this.transformWithHtmlBase(
'<a href="test/">Link</a>',
"http://example.com/"
)}
=> '<a href="http://example.com/pathprefix/my-template/test/">Link</a>'
Override the page URL:
${await this.transformWithHtmlBase(
'<a href="test/">Link</a>',
"http://example.com/",
"/my-other-template/"
)}
=> '<a href="http://example.com/pathprefix/my-other-template/test/">Link</a>''`;
};
With path prefix set to "/pathprefix/"
:
module.exports = async function () {
return `
${await this.transformWithHtmlBase(`<a href="/test/">Link</a>`)}
=> '<a href="/pathprefix/test/">Link</a>'
${await this.transformWithHtmlBase(
`<a href="/test/">Link</a>`,
"http://example.com/"
)}
=> '<a href="http://example.com/pathprefix/test/">Link</a>'`;
};
Resolving relative URLs (with path prefix still at "/pathprefix/"
):
module.exports = async function () {
return `
On a page with URL "/my-template/":
${await this.transformWithHtmlBase(
'<a href="test/">Link</a>',
"http://example.com/"
)}
=> '<a href="http://example.com/pathprefix/my-template/test/">Link</a>'
Override the page URL:
${await this.transformWithHtmlBase(
'<a href="test/">Link</a>',
"http://example.com/",
"/my-other-template/"
)}
=> '<a href="http://example.com/pathprefix/my-other-template/test/">Link</a>''`;
};
addPathPrefixToFullUrl
Note that passing a full external URL (e.g. http://example.com/
) to htmlBaseUrl
will return the URL unchanged. We don’t want to add pathPrefix
to external links!
However, if you do want to force addition of pathPrefix to a URL, you can use the addPathPrefixToFullUrl
filter.
With path prefix set to "/pathprefix/"
:
{{ "http://example.com/" | addPathPrefixToFullUrl }}
=> "http://example.com/pathprefix/"
With path prefix set to "/pathprefix/"
:
{{ "http://example.com/" | addPathPrefixToFullUrl }}
=> "http://example.com/pathprefix/"
With path prefix set to "/pathprefix/"
:
export default function () {
return this.addPathPrefixToFullUrl("http://example.com/");
// "http://example.com/pathprefix/"
};
With path prefix set to "/pathprefix/"
:
module.exports = function () {
return this.addPathPrefixToFullUrl("http://example.com/");
// "http://example.com/pathprefix/"
};