I am currently working on a 11ty project and really like it. But I have a problem with the links when I deploy the output. I'd like to deploy it to 2 different locations on separate servers. One of the locations is in the root directory, the other one in a sub-folder. It works like a charm for the one that is located in the root directory, but the other doesn't since all the paths are incorrect.
Is it possible to have relative links in the output?
I already tried pathPrefix, but either I don't use it properly or it just doesn't give me the result I am looking for.
.eleventy.js:
module.exports = eleventyConfig => {
...
// Include our static assets
eleventyConfig.addPassthroughCopy("images")
return {
pathPrefix: "/subfolder/",
templateFormats: ["md", "njk"],
markdownTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
passthroughFileCopy: true,
dir: {
input: 'site',
output: 'dist',
includes: 'includes',
data: 'globals',
}
}
}
When I run eleventy --config=eleventy.config.js --serve, an additional folder gets generated with the name _eleventy_redirect, including an index.html file with:
<!doctype html>
<meta http-equiv="refresh" content="0; url=/subfolder/">
<title>Browsersync pathPrefix Redirect</title>
<a href="/subfolder/">Go to /subfolder/</a>
When I run eleventy --config=eleventy.config.js (without the --serve), that folder isn't there.
However, either way all the links are absolute (e.g. Home is href="/"), and the site doesn't work on the server.
Is there a way to have either relative links (e.g. Home is href="./" on the root index.html and href="../" on sub pages) or at least include the subfolder in the urls (e.g. Home is href="./subfolder/")?
Try href="{{ "/" | url ))", the url filter should take care of this. Imo always add the url filter to links to avoid issues later.
I'm trying solve same problem, and I'm actually using root variable.
Not perfect but it's working.
root = "../" for page in subfolder in front matter.<link rel="stylesheet" href="{{ root }}assets/styles/index.css">Maybe it's good enough for you too :)
My solution was to add a relative path filter.
eleventyConfig.addFilter(
"relative",
(page, root = "/") =>
`${require("path").relative(page.filePathStem, root)}/`
);
<link rel="stylesheet" href="{{ page | relative }}styles/index.css">
Thanks @mpalpha !
I tinkered a bit with the filter, here's my version of it:
eleventyConfig.addFilter('relativeUrl', (url, page) => {
if (!url.startsWith('/')) {
throw new Error('URL is already relative')
}
const relativeUrl = path.relative(page.filePathStem, url)
return path.relative('..', relativeUrl)
})
<link rel="stylesheet" href="{{ '/css/vendor.css' | relativeUrl(page) }}">
I don't know if this is related, but I am running into issues using Typora with 11ty.
My markdown links in Typora are like this: [My page](my-page.md). The top links work fine, but if I am on a subpage, the link slug gets added to that subpage.
For example if I am on example.com/pages/cool-page and I click the link My page, I get to a wrong url example.com/pages/cool-page/my-page.
Is there a way to make it so all links are at example.com/pages?
I have no idea, I don't use Typora. Maybe you could create a markdown function to replace a string with the current relative path.
[My page](@[email protected])
For example if I am on
example.com/pages/cool-pageand I click the linkMy page, I get to a wrong urlexample.com/pages/cool-page/my-page.
Isn't that the correct behavior [since the markdown link is relative and not absolute)? If you want it to be example.com/my-page, style, I think you'd have to do [My page](/my-page.md).
If I change my markdown links, then I am not able to navigate in my markdown editor (Typora). Doing [My page](/my-page.md) brakes the link.
For every page I define a permalink: /posts/my-page/ or /articles/some-article/ . But all markdown files are in the same directory: my-page.md and some-article.md.
I'm not sure then, sorry.
Sounds like this was resolved, thanks folks!
@edgarasben please file your issue separately!
@zachleat I think I did? https://github.com/11ty/eleventy/issues/1197
I ended up going with a global {{ rootPath }} variable which is relative to the current page.
Inside your data directory create a file called eleventyComputed.js
edited: switched to .reduce and added a filter
module.exports = {
rootPath: (data) =>
data.page.url
.split('/')
.reduce((a, b) => a+(b && '../'),)
}
{{ rootPath }}
or
const Path = require('path')
eleventyConfig.addFilter("relative", function (url) {
return Path.join(
'./',
this.ctx.page.url.split('/').reduce((a, b) => a + (b && '../')),
url
)
})
{{ page.url | relative }}
Thanks @mpalpha
I'm edited you solution little bit, because i钮 not working when the site is in folder.
module.exports = {
rootPath: function(data) {
return data.page.url
.split('/')
.filter(function(x) {
return x;
})
.map(function() {
return '../';
})
.join('');
}
}
And then use it like this: {{ rootPath }}assets/styles.css
I am having the same issue since I am working with a Website hosted in a subfolder. I managed to change the urls for css stylesheets and thumbnails images, however I did not succeed in changing them for posts urls.
Most helpful comment
My solution was to add a relative path filter.