-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Customizing html template #14195
Comments
My dude, I just wanted to thank you so much for this explanation. I know its about the issue I posted and I think it would be an awesome extension of functionality. |
Custom html template was fairly easy to use when we needed to append GTM scripts in a really quick way. For example, let's say this is the html template: <!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD_PREPEND }}
{{ HEAD }}
{{ HEAD_APPEND }}
</head>
<body {{ BODY_ATTRS }}>
{{ BODY_PREPEND }}
{{ APP }}
{{ BODY_PREPEND }}
</body>
</html> And i want to override BODY_PREPEND in a verbose manner, without passing from <script src="https://something.com/some-lib.html" />
<div> This will be inserted in body_prepend placeholder </div> WDYT? |
While I can see how intuitive it is for people coming from other frameworks, I'm afraid that an |
That's fair. {
hid: "gtm",
children: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');
`,
type: "text/javascript",
}, Looks awful and cumbersome. Any ideas on how to make it more elegant? |
I agree about DX points of verbosity introduced to It is probably most convenient if there is a module to add 3rd party scripts and we are working on But I also like the idea of having an |
IMHO there should be at least a |
I'm not saying it doesn't make sense or usecase. Object API as well as modules (local or external) have the full possibility to inject in all possible positions. And this is probably super temporary since with Do you have some common integration examples can benefit from |
I see. Indeed makes sense for gtm for exact copy-paste BTW I wouldn't personally add no-script to a Nuxt app since without script Nuxt app is probably not working too and doesn't respect Users privacy when scripts are explicitly disabled by the browser. analytics scripts like to take over with the highest priority regardless of performance implications or user preferences 😅 Okay then regardless I think this all means we should accelerate to deliver |
It does matter, because GTM could be used to track page events and could even have conditions firing on some Yet, I believe we should still be able to exploit compile-time pre-processing for optimizations. <!-- page.vue -->
<script setup>
const gtm = "XXX"
</script>
<template>
<div>
<Head>
<Script type="text/javascript" fetchpriority="high">
// code using the {{ gtm }} variable
</Script>
</Head>
...
</div>
</template> This would be more in line with Nuxt's approach to head management, and still could be reduced to the cases where bad companies like Google force you to copy/paste 3rd-party scripts. Edit: Of course, the Edit #11665: maybe we could exploit Google's new fetchpriority (https://web.dev/priority-hints/) to inform the compiler about the order/priority. |
If the website is fully statically generated, it should be able to be navigated even when there's no javascript going, therefore |
That's not true, unfortunately. SSG means that the possible routes result in pre-generated HTML pages, but still, the dynamic data and reactivity will be handled by client-side javascript (the pre-generated pages don't have statically all the information, they are just better for SEO and can avoid server-side logic). |
This website is "usable" with javascript disabled. It uses bridge + nitro. Menu doesn't work (because it's not implemented to be used with zero-javascript, although you can make a fallback), but you can still navigate the website (since SSR-wise nuxtLinks are rendered as anchor tags) and you can see contents. Btw, this discussion is not meant to be taken here :) |
Just a comment about my use case, I am using Nuxt 3 and ionic to generate an ios app. While most css classes are standard a-zA-Z the moment I added FormKit (which is meant to be nuxt 3 compatible). It would leave a blank screen due to this error
All this to say that if I had a way to update the index.html generated to have a charset metatag of utf-8 the problem would go away. As of now I have to manually add it before deploying to ios every single time I generate the nuxt app or remove a really useful form package. Using useHead wouldn't work since css is loaded before js so nuxt cannot load itself hence the blank screen. Just hoping this is resolved soon 👍🏽 |
@Rigo-m btw did you look at this way of setting GTM? @jvrsolis this is a bug per-se, did you report it? Meta-charset and few other tags should be the first in the . |
I think this would also be needed to use a Plugin like this https://github.com/hoiheart/vue-universal-modal#install-plugin |
@jvrsolis You should be able to set the charset with: import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
app: {
head: {
charset: 'utf-8'
}
}
}) But utf-8 should actually be the default value and if this is not being generated it's a (separate) bug - do raise a new issue. |
I still only get a file with the following when running nuxi generate. This file is what appears in safari and in the ios app inspect. No utf-8 meta tag so blank screen
This is my current nuxt config
|
You need to set |
We have a need to insert something like the following at the top of our HTML document ( above everything else ). It is used by a corporate proxy that then uses the information inside of it to render an appropriate template and header/footer. in our Nuxt2 apps, we put this snippet at the top of the app.html file. I am wondering how we might do this in nuxt3 without the app.html or something equivalent?
|
Some news about app.html in Nuxt 3? |
@vaban-ru There are now extensive hooks that allow you to customise the rendering of your app. In your case, you would probably want to use the Nitro hook |
@danielroe I have been using the app:templates hook to override the getContents method of views/document.template.mjs. Since nuxt/framework@f58aa81 this is no longer possible and the HTML template itself is hard coded. Could you elaborate how the nitro hook render:html could be used? To give some context: We use ESI tags to inject some HTML into each Document right before it is send to the user. This also means these tags will be replaced by some markup on the client. Therefore we cannot use anything that is managed by e.g. Vue on the client without triggering hydration mismatch. An example: <!DOCTYPE html>
<html ${joinAttrs(html.htmlAttrs)} data-custom="value">
<head>${joinTags(html.head)}<!--esi <esi:include src="/some/stuff" /> --></head>
<body ${joinAttrs(html.bodyAttrs)}><!--esi <esi:include src="/more/stuff" /> -->${joinTags(html.bodyPreprend)}${joinTags(html.body)}${joinTags(html.bodyAppend)}</body>
</html> EDIT
import { defineNitroPlugin } from 'nitropack/runtime/plugin'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
html.head.push('<!--esi <esi:include src="/some/stuff" /> -->')
})
}) This should work. Similar to |
This solution above by @pierres worked for me. In my case, I wanted a // server/plugins/nitroPlugin.ts
import { defineNitroPlugin } from 'nitropack/runtime/plugin'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
html.bodyAppend.push(`<div id="modal-root"></div>`)
})
}) It barked a little about not finding the module 'nitropack/runtime/plugin' but it still worked just fine. No need to import in the |
Yes, we are aware of it, hence my initial answer to you. |
This issue will pop up to anyone who is googling Nuxt3 Google Analytics. GA on their own are very frustrating, so maybe let's introduce a way for developers how to quickly get things done with GA and Nuxt3? :) |
What about this? It works perfectly since RC1 I think. https://nuxt.com/docs/guide/directory-structure/plugins#vue-plugins |
It works with Google Tag but what about Google Tag Manager (Here are the differences: https://support.google.com/tagmanager/answer/7582054?hl=en)? We have a script to put at the top of the head and a noscript to put at the top of the body. I don't see a solution yet. |
@ThomasBerneSV Please open a discussion with the code you are trying and we'll do our best to advise; this should be very possible using |
@danielroe here is the discussion link: https://github.com/nuxt/framework/discussions/9590 |
@danielroe I didn't received an answer. Did you see the discussion? |
@ThomasBerneSV he probably did, no need to ping him on both sides. |
Are issue alive? Need posibility to modify base HTML template. |
@DAVIDhaker I think the important parts to modify the base HTML template are there by now |
For anyone looking for a way to include some custom html attributes, the solution that @pierres brings works like a charm! // at server/plugins/html.render.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
html.htmlAttrs.push("data-theme='light'")
})
}) |
How change nitroApp.hooks.hook('render:html' Need the server. But I only want a SPA page.... |
That hook will also be called when prerendering the |
Ok! thanks a lot! |
Any update on this feature? |
The feature already exists (see nuxt/framework#6042) but lacks documentation |
For those dealing just with GTM - there's a nowadays package https://github.com/zadigetvoltaire/nuxt-gtm, but it doesn't work for However, the solution with |
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:
This is the anatomy of the built-in template as a standard HTML structure:
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:
(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.
The text was updated successfully, but these errors were encountered: