Arbitrary head tags with Head.nonLoadingNode, and loading head tags with headTagsTemplate #339
dillonkearns
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
The question has come up a lot on how to add arbitrary
<head>
tags that aren't exposed through theHead
API.I've added a way to do arbitrary global head tags for v3 through the
elm-pages.config.mjs
file, like in this example: https://github.com/dillonkearns/elm-pages-v3-beta/blob/6a067671200f896c2a9b10a31aab307f88943973/examples/docs/elm-pages.config.mjs#L12-L15.I've also added a way to do route-specific non-loading head tags in Elm, described in the non-loading tags section below.
Loading tags
The idea behind it is that since v3 introduces a Vite integration, there should be a way to add
<head>
tags which Vite can process. So if you wanted to include a SASS (.scss
) file, you could do so in theheadTagsTemplate
in your config and your Vite configuration will run to preprocess that. Vite also has an API for adding preload directives for tags it processes. I exposed a config hook,preloadTagForFile
, to customize which tags to include preload tags for, or customize how to render the preload tag (full discussion of that API in #337).So that's the elm-pages v3 functionality for loading scripts/assets. I think it's pretty comprehensive and full-featured. One thing I can imagine in the future is a way to let users pass in values from Vite to a Route Module so you can load values and have them pre-processed through Vite but access the resulting values in Elm. This might be a good way to support lazy-loading assets on route changes through Vite (this is the main thing that isn't supported through the current design I believe). I opened a discussion thread for that idea: #338. Otherwise, I think this covers the main use cases for loading pretty well, including adding arbitrary script tags to things like 3rd party scripts. If I'm missing any use cases that this doesn't support well, though, I'd love to hear about them.
Non-loading tags
There have been a lot of questions about how to add arbitrary
<head>
tags, as there are a lot of possible tags and it's not possible to exhaustively list every possible current and future tag.I've introduced a new design for this in v3. Importantly, this is for non-loading tags. Loading tags, like
<script src="my-script.js">
and preloading directives like<link rel="preload" href="/my-script.js" as="script" />
are covered by the above design. The thinking is that those loading tags are special because they are best handled by Vite since:And also that loading tags perform side-effects, whereas the design goal for the elm-pages
Head
API is to be a declarative way to describe metadata like SEO tags, not to perform loading/pre-loading effects. That way you can reason about them in a more pure and deterministic way.A few considerations here:
Head
API only runs when pre-rendering/server-rendering the page. It is never run on the client-side. This allows us to eliminate thehead
function from the client-side bundleSo the new
Head.nonLoadingNode
will allow for any arbitrary head tag that isn't a loading/pre-loading directive.For example, the following
nonLoadingNode
tags:Will result in the following warnings printed when running
elm-pages build
:The build will then exit with a successful exit code, and the output will not include the above
<script />
or<link ... />
tag.Feedback
If you have any use cases that aren't well supported by the design, I'd love to hear about your concrete use cases and the pain points that aren't addressed here. Or general feedback on design details here or the overall architecture are welcome as well. Thanks for reading!
Beta Was this translation helpful? Give feedback.
All reactions