Closed jimafisk closed 3 years ago
This would be helpful for spinning up demo sites for themes on https://github.com/plenti-themes using github pages.
I would love to not have to prepend every link with something like <a href="{site.baseurl}/about">
in order for this to work.
You could almost use the HTML5 standard <base>
element to accomplish something like this. It would require devs to rig this up themselves outside of plenti, but that might even be desirable. Just add something like this to your <head>
:
<base href="/mysubdir/">
Unfortunately this will only work with relative urls, not root relative urls (the difference). If you're like me and all your links are root relative, you'll need to remove the forward slash at the beginning of each of them, or just add a period .
to the front, which is typically easier to accomplish.
Sounds easy enough, there are just a few small things still getting in the way:
Your server rendered HTML probably works fine, but plenti adds the following scripts behind the scenes to actually hydrate the app so unless we update this it won't convert the root relative data-main
to a relative link that will work with a sub directory:
<script type='module' src='https://unpkg.com/dimport?module' data-main='/spa/ejected/main.js'></script>
<script nomodule src='https://unpkg.com/dimport/nomodule' data-main='/spa/ejected/main.js'></script>
Using the <base>
element will break your local site. You could assign a dot .
prefix to a variable and manually switch it to an empty string for local dev, but that's a pain. It would be nicer to figure this out automatically with something like let baseurl = location.hostname === "localhost" ? "" : ".";
but the server rendered html uses v8 which doesn't have any awareness of the window.location
object. It would be nice if we had a mechanism to determine if we're on a local build or not.
If you have HTML in your JSON source that you're rendering in your templates via @html
, it's going to be hard to inject a relative .
to the front of paths. This is coming from your content source, so you could just make a policy of setting it there but it won't be flexible for the local/deployed problem presented in 2.
Conversation about baseurl in jekyll: https://github.com/jekyll/jekyll/issues/332
The best solution I've come up with is to add new local
and baseurl
magic props so you can do something like this in head.svelte
:
<script>
export let title, local, baseurl;
let baseEl = local ? "/" : baseurl;
</script>
<head>
<title>{ title }</title>
<base href="{ baseEl }">
</head>
The local
variable should set automatically when using local server for SSR and through observing the site url for DOM. The baseurl
variable should be set in plenti.json
so it can be adjusted when used in a theme without having to override the parent template.
This way we don't force users to prepend every url with a variable and it should work locally and on remote sites without having to set any build flags.
There is a new env
special prop / magic variable added in v0.4.17 that should allow you to accomplish this. Check out the example in the "learner" default starter for usage details: https://github.com/plentico/plenti/blob/9dd63555b27b1d88c002dd13d026b37677867b6d/cmd/defaults/starters/learner/layouts/global/head.svelte#L11
There's a issue with core paths getting to root relative equivalents.
This can be seen at https://plenti-themes.github.io/bigspring/spa/ejected/main.js: import Router from '/spa/ejected/router.js';
And all exports in https://plenti-themes.github.io/bigspring/spa/ejected/layouts.js.
The HTML fallbacks will be created fine, but the client app won't work properly in a subfolder until this is addressed.
I killed the forced redirects for trailing slashes (https://github.com/plentico/plenti/pull/158/commits/3a8185fe98a0d7a617e54a907fb6986c0bcb6f4b) because when you're replacing with a relative url, it would get appended to the end of the current url:
I also figured it was better not to dictate this behavior because it prevented users from using urls that end with trailing slashes in their SPA. Now users have the choice to use trailing slashes or remove them. The caveat is when doing a hard refresh on a page, static html automatically loads with the trailing slash (e.g. mysite.com/about/
which is really mysite.com/about/index.html
). This will render just fine still and if your links all do not have trailing slashes, that's how the routes will appear if they navigate once the SPA has taken over.
We were still getting the following errors in the console:
Uncaught TypeError: Cannot read property 'type' of undefined
(Chrome)Uncaught TypeError: content is undefined
(Firefox)This is because the uri
has the baseurl prepended to it, so the content lookup fails:
We can add some regex to main.js to remove this before the lookup:
The client router is defaulting to handle404()
because it's not matching any routes:
This can be fixed by having the navaid router take the baseurl into account:
router.on(env.baseurl + content.path, () => {...}
For the bigspring site that works fine, we probably just want to preprocess this to account for all edge cases (e.g. content.path
is relative or root relative, the baseurl
has a trailing slash or not, etc).
Other SSGs like Jekyll and Hugo have a concept of
baseurl
which allows you serve your website from a url that has a sub directory, e.g.https://my-group.gitlab.io/my-project
. I'm not sure I love the idea of calling this "baseurl" but that does seem to be the convention (11ty calls this pathprefix, Gatsby does too ). Here are some other potential names:root (like hexo)
This should be able to be configured in
plenti.json
or passed as a flag to thebuild
/serve
commands.