Next.js - 如何在 <head> 内添加一个 <link> 标签,带有文字 onload 属性字符串值?
Next.js - How to add a <link> tag inside the <head> with literal onload attribute string value?
在一个 Next.js 项目中,我想在 <head>
:
中获得一些具有完全相同内容的初始 HTML
<link href="..." rel="stylesheet" media="print" onload="this.media='all'" />
我在 Next.js 的 <Head>
组件中的代码是:
{ /* @ts-ignore */ }
<link href="..." rel="stylesheet" media="print" onload="this.media='all'" />
没有 @ts-ignore
它说:
Property 'onload' does not exist on type 'DetailedHTMLProps<LinkHTMLAttributes, HTMLLinkElement>'. Did you mean 'onLoad'? ts(2322)
如果我使用 onLoad
而不是 onload
我得到:
Type 'string' is not assignable to type '(event: SyntheticEvent<HTMLLinkElement, Event>) => void'. ts(2322)
问题是我得到的服务器端生成的 HTML 有:
<link href="..." rel="stylesheet" media="print" />
只有在页面重新水化后才会更新为:
<link href="..." rel="stylesheet" media="all" onload="this.media='all'">
我在 GitHub 上发现了这个问题,但它没有帮助,因为我没有使用 Google 字体,而是 Typography.com,所以我不能使用 next-google-fonts
: https://github.com/vercel/next.js/issues/12984
我正在考虑向那个 link
标记添加一个 ref
并使用 setAttribute
设置属性,这有望在服务器端工作,但想知道如果有更简单的方法。
所以我最终使用带有 dangerouslySetInnerHTML
in a custom _document.js
的 <style>
标签修复了这个问题。它应该看起来像这样:
<link rel="preconnect" href="https://fonts.googleapis.com" crossOrigin="anonymous" />
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" as="style" />
<style dangerouslySetInnerHTML={ {
__html: `</style>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap"
media="print"
onload="this.media='all';"
/>
<style>`
} }></style>
<noscript>
<link
rel="stylesheet"
type="text/css"
href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" />
</noscript>
生成以下输出:
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin="anonymous"/>
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" as="style"/>
<style></style>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" media="print" onload="this.media='all';" />
<style></style>
<noscript><link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap"/></noscript>
不漂亮,但比 <head>
中的 <div>
要好(并非所有浏览器都能正确解释)。
有一个 open RFC 可以创建一个 RawHTML
组件或扩展 Fragment
以接受 dangerouslySetInnerHTML
这样就可以在没有 hack 的情况下实现这样的事情,但它已经超过自创建以来一年。
此外,还有 quite a long discussion about this 以及一些似乎有效的不同解决方案(技巧)。
您可以在此处查看有效的解决方案:https://andorratechvalley.com/
在一个 Next.js 项目中,我想在 <head>
:
<link href="..." rel="stylesheet" media="print" onload="this.media='all'" />
我在 Next.js 的 <Head>
组件中的代码是:
{ /* @ts-ignore */ }
<link href="..." rel="stylesheet" media="print" onload="this.media='all'" />
没有 @ts-ignore
它说:
Property 'onload' does not exist on type 'DetailedHTMLProps<LinkHTMLAttributes, HTMLLinkElement>'. Did you mean 'onLoad'? ts(2322)
如果我使用 onLoad
而不是 onload
我得到:
Type 'string' is not assignable to type '(event: SyntheticEvent<HTMLLinkElement, Event>) => void'. ts(2322)
问题是我得到的服务器端生成的 HTML 有:
<link href="..." rel="stylesheet" media="print" />
只有在页面重新水化后才会更新为:
<link href="..." rel="stylesheet" media="all" onload="this.media='all'">
我在 GitHub 上发现了这个问题,但它没有帮助,因为我没有使用 Google 字体,而是 Typography.com,所以我不能使用 next-google-fonts
: https://github.com/vercel/next.js/issues/12984
我正在考虑向那个 link
标记添加一个 ref
并使用 setAttribute
设置属性,这有望在服务器端工作,但想知道如果有更简单的方法。
所以我最终使用带有 dangerouslySetInnerHTML
in a custom _document.js
的 <style>
标签修复了这个问题。它应该看起来像这样:
<link rel="preconnect" href="https://fonts.googleapis.com" crossOrigin="anonymous" />
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" as="style" />
<style dangerouslySetInnerHTML={ {
__html: `</style>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap"
media="print"
onload="this.media='all';"
/>
<style>`
} }></style>
<noscript>
<link
rel="stylesheet"
type="text/css"
href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" />
</noscript>
生成以下输出:
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin="anonymous"/>
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" as="style"/>
<style></style>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap" media="print" onload="this.media='all';" />
<style></style>
<noscript><link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap"/></noscript>
不漂亮,但比 <head>
中的 <div>
要好(并非所有浏览器都能正确解释)。
有一个 open RFC 可以创建一个 RawHTML
组件或扩展 Fragment
以接受 dangerouslySetInnerHTML
这样就可以在没有 hack 的情况下实现这样的事情,但它已经超过自创建以来一年。
此外,还有 quite a long discussion about this 以及一些似乎有效的不同解决方案(技巧)。
您可以在此处查看有效的解决方案:https://andorratechvalley.com/