Nuxt bridge is not adding the head metadata into the initial loading HTML file.
Environment
Nuxt CLI v3.0.0-27460146.2ad93eb
RootDir: /projects/nuxt
Nuxt project info:
- Operating System:
Darwin - Node Version:
v16.14.2 - Nuxt Version:
2.16.0-27358576.777a4b7f - Package Manager:
[email protected] - Builder:
webpack - User Config:
telemetry,ssr,bridge,head,env,loading,css,plugins,router,modules,axios,build,buildModules,server - Runtime Modules:
@nuxtjs/[email protected],@nuxtjs/[email protected],@nuxtjs/[email protected] - Build Modules:
@nuxtjs/[email protected],@nuxt/[email protected]
Reproduction
Updated package.json as follows: "nuxt": "^2.14.12", -> "nuxt-edge": "latest",
+"@nuxt/bridge": "npm:@nuxt/bridge-edge@^3.0.0-27460146.2ad93eb", +"@nuxt/devalue": "^2.0.0", +"std-env": "^3.0.1", -- added because of nuxt/bridge#175
"dev": "nuxi dev",
npm run dev
Describe the bug
Nuxt bridge is not adding the head metadata into the initial loading HTML file.
Following is config after upgrade:
import { defineNuxtConfig } from "@nuxt/bridge";
export default defineNuxtConfig({
telemetry: false,
ssr: false,
/*
** Headers of the page
*/
head: {
title: 'name',
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "description", name: "description", content: pkg.description },
],
link: [
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
{
rel: "stylesheet",
href: "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons",
},
],
script: [
{ src: "https://unpkg.com/lodash@latest/lodash.min.js" },
{ src: "https://unpkg.com/dayjs@latest/dayjs.min.js" },
],
},
});
After using bridge

Before using bridge

Additional context
No response
Logs
WARN Compiled with 1 warnings friendly-errors 11:51:27
WARN in ./node_modules/fflate/esm/index.mjs friendly-errors 11:51:27
Module not found: Error: Can't resolve 'worker_threads' in '/Users/sasank/Documents/adt/projects/erp-nuxt/node_modules/fflate/esm'
friendly-errors 11:51:27
ℹ Waiting for file changes 11:51:27
✔ Nitro built in 313 ms
same here
I am having a similar issue with missing head meta tags after transitioning a Nuxt 2 SPA ssr: false that was using @nuxtjs/composition-api to nuxt-bridge using Nuxt CLI v3.0.0-rc.4-27588443.cf25525
When deploying the site to production on Vercel the Social Cards that are set using meta tags in nuxt.config.js no longer work and the <head> tag is empty on the initial HTML File (screenshot below of curl on the production app using nuxt-bridge)

Something else I've noticed. Upon inspecting the source of the nuxt-bridge production site after the SPA has loaded all the meta tags. For Nuxt-bridge all of the meta tags are towards the bottom of <head> after all of the <style> and <link> tags where the <meta> tags used to be at the top of <head> in Nuxt 2 and in the order in which they were specified in the nuxt.config.js.
Not sure if order matters in <head> but regardless the order is now different in nuxt-bridge, perhaps a clue to the underlying issue here.
I'm also having this issue attempting to upgrade from nuxt 2 to nuxt bridge. Are there any known work arounds for now?
EDIT: https://github.com/nuxt/bridge/issues/27#issuecomment-1097947064 appears to fix this for now.
Is there a known way to inject the meta stuff manually in the head of the index.html?
maybe some hook I could add?
Edit:
Either I do it wrong or the generate:page hook doesn't work anymore.
I try to edit the html variable, but the generated index.html stays the same @danielroe .
Edit0: I try to use
bridge: {
meta: true
}
but it throws the error @vueuse/head not found.
Manually installing throws the error that it needs vue 3.x.
I manually forced the installation of the package.
Using it like in the bridge docs also doesn't work.
There is still no content in the <head> section.
It seems that I need to add a hook outside of the nuxtJS framework to add the needed <meta> in the <head> section.
Edit1: Finally a working workaround to add the header back:
hooks: {
generate: {
done(generator) {
let extraFilePath = path.join(generator.distPath, 'index.html')
fs.writeFileSync(
extraFilePath,
fs
.readFileSync(extraFilePath)
.toLocaleString()
.replace(
'<head>',
`<head>
<title>Title</title>
<meta data-n-head="1" charset="utf-8">
<meta data-n-head="1" content="width=device-width,initial-scale=1" name="viewport">
<meta data-n-head="1" content="" data-hid="description" name="description">
<meta data-n-head="1" content="telephone=no" name="format-detection">
<link data-n-head="1" href="/favicon.ico" rel="icon" type="image/x-icon">`
)
)
extraFilePath = path.join(generator.distPath, '200.html')
fs.writeFileSync(
extraFilePath,
fs
.readFileSync(extraFilePath)
.toLocaleString()
.replace(
'<head>',
`<head>
<title>Title</title>
<meta data-n-head="1" charset="utf-8">
<meta data-n-head="1" content="width=device-width,initial-scale=1" name="viewport">
<meta data-n-head="1" content="" data-hid="description" name="description">
<meta data-n-head="1" content="telephone=no" name="format-detection">
<link data-n-head="1" href="/favicon.ico" rel="icon" type="image/x-icon">`
)
)
},
},
},
But it's still broken, if I access a url path directly instead via the router.
It will result in an html file with empty <head>.
Edit2:
A better solution is to create a app.html file at the root of your project:
<!-- TODO WORKAROUND FOR https://github.com/nuxt/bridge/issues/20
REMOVE FILE AFTER FIXED!-->
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
<title>Title</title>
<meta data-n-head="1" charset="utf-8">
<meta data-n-head="1" content="width=device-width,initial-scale=1" name="viewport">
<meta data-n-head="1" content="" data-hid="description" name="description">
<meta data-n-head="1" content="telephone=no" name="format-detection">
<link data-n-head="1" href="/favicon.ico" rel="icon" type="image/x-icon">
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
This does not appear to be occurring in the latest version. Let me know if not; I'm happy to reopen.
Hey @wattanx, bug still happens within the latest version when using ssr: false, I just created a minimal repo for testing:
https://github.com/onlurking/nuxt-bridge-meta-poc
Ouput when using ssr: false:
<!DOCTYPE html>
<html >
<head >
<link rel="modulepreload" as="script" crossorigin href="/_nuxt/1b8a5db.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/2b79740.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/7ce7b7d.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/d7f6c67.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/1fa85a8.js">
</head>
<body >
<div id="__nuxt"></div><script>window.__NUXT__=(function(a,b){return {serverRendered:false,config:{public:{},app:{baseURL:a,basePath:a,assetsPath:b,cdnURL:"",buildAssetsDir:b}}}}("\u002F","\u002F_nuxt\u002F"))</script><script type="module" src="/_nuxt/1b8a5db.js" crossorigin></script><script type="module" src="/_nuxt/2b79740.js" crossorigin></script><script type="module" src="/_nuxt/7ce7b7d.js" crossorigin></script><script type="module" src="/_nuxt/d7f6c67.js" crossorigin></script>
</body>
</html>
With ssr: true:
<!DOCTYPE html>
<html >
<head >
<title>Nuxt.js starter for CSB</title><meta data-n-head="ssr" charset="utf-8"><meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1"><meta data-n-head="ssr" data-hid="description" name="description" content="Official Nuxt.js starter for CodeSandBox"><link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/5452fdc.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/ae4ca0a.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/bc5cfe3.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/d7f6c67.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/1fa85a8.js"><style data-vue-ssr-id="38b0ce29:0">.nuxt-progress{background-color:#000;height:2px;left:0;opacity:1;position:fixed;right:0;top:0;transition:width .1s,opacity .4s;width:0;z-index:999999}.nuxt-progress.nuxt-progress-notransition{transition:none}.nuxt-progress-failed{background-color:red}</style>
</head>
<body >
<div data-server-rendered="true" id="__nuxt"><!----><div id="__layout"><div></div></div></div><script>window.__NUXT__=(function(a,b){return {layout:"default",data:[{}],fetch:{},error:null,serverRendered:true,routePath:a,config:{public:{},app:{baseURL:a,basePath:a,assetsPath:b,cdnURL:"",buildAssetsDir:b}},_asyncData:{},_errors:{}}}("\u002F","\u002F_nuxt\u002F"))</script><script type="module" src="/_nuxt/5452fdc.js" crossorigin></script><script type="module" src="/_nuxt/ae4ca0a.js" crossorigin></script><script type="module" src="/_nuxt/bc5cfe3.js" crossorigin></script><script type="module" src="/_nuxt/d7f6c67.js" crossorigin></script>
</body>
</html>
Using bridge: { meta: true } doesn't work either.
Versions:
Nuxt: both "nuxt": "^2.17.0" and "nuxt-edge 2.17.1-28131860.8edc36e" @nuxt/bridge "nuxt/bridge-edge@^3.0.0-28132497.798694a" Node: v16.20.0