-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Customizing html template #14195
Description
History: In Nuxt 2, we were supporting the ability to provide a custom HTML template used for the renderer. While it was simple, several issues:
- Only could be customized once by end-users (modules cannot hook to extend it and had to use other methods for injection)
- Can be outdated if we wanted to add a new placeholder for the built-in template
- Additional spaces or code format for customization can break hydration behavior
- With Nitro and moving to standalone server builds, we had to convert it into a JS function
- Different behavior for SSR/SPA is not covered
- Runtime level customizations are not possible
- Opaque behavior without ability to inspect by Nuxt
This is the anatomy of the built-in template as a standard HTML structure:
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>The main use-case of providing a custom template is extending placeholders to add a global static script or style or attributes. With Nuxt 3, I'm proposing to have a configuration interface in order to extend template:
export default defineNuxtConfig({
template: {
htmlAttrs: [],
headAttrs: [],
headPrepend: [],
headPrepend: [],
bodyAttrs: [],
bodyPrepend: [],
bodyAppend: []
}
})(note: we shall make it consistent with RenderResult.meta interface)
This interface is forward-compatible, predictable, easily configurable and extandable by modules and always leads to a valid HTML output.
More dynamic customization and runtime behavior can be provided by nuxt:render hooks (#14182).
There was also an initial discussion to provide the ability completely override the template as an escape hatch. I believe unless it is proven there is a valid use case that cannot be supported by the Object interface, it is probably safer to not expose it. There might be cases we want to compile something that is not HTML (like a Native output?) but this probably deserves better refactor on renderer implementation to expose an API and allow full overriding renderer file, taking into account it is not rendering HTML.