Next.js - 如何添加 &lt;link&gt;<head> 内的标签带有文字 onload 属性字符串值? [英] Next.js - How to add a &lt;link&gt; tag inside the &lt;head&gt; with literal onload attribute string value?

查看:66
本文介绍了Next.js - 如何添加 &lt;link&gt;<head> 内的标签带有文字 onload 属性字符串值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Next.js 项目中,我想在 <head> 中获得一些具有完全相同内容的初始 HTML:

在 Next.js 的 <Head> 组件中,我的代码中有:

{/* @ts-ignore */}<link href="...";rel=样式表"媒体=打印"onload="this.media='all'";/>

没有 @ts-ignore 它说:

<块引用>

属性onload"在类型DetailedHTMLProps"上不存在.您指的是 'onLoad' 吗?ts(2322)

如果我使用 onLoad 而不是 onload 我得到:

<块引用>

类型 'string' 不可分配给类型 '(event: SyntheticEvent) =>空白'.ts(2322)

问题是我得到的服务器端生成的 HTML 有:

并且只有在页面重新水化后,它才会更新为:

我在 GitHub 上发现了这个问题,但它没有帮助,因为我使用的不是 Google 字体而是 Typography.com,所以我无法使用 next-google-fonts:https://github.com/vercel/next.js/issues/12984

我正在考虑将 ref 添加到该 link 标记并使用 setAttribute 设置属性,这有望在服务器上运行-side 也是如此,但想知道是否有更简单的方法来做到这一点.

解决方案

所以我最终使用 <style> 标签和 dangerouslySetInnerHTML自定义 _document.js.总的来说,它应该是这样的:

生成以下输出:

<link rel=预加载"href=https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&amp;family=Karla:wght@700&display=swap"as=风格"/><style></style><link rel="样式表";href=https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&family=Karla:wght@700&display=swap"媒体=打印"onload="this.media='all';"/><style></style><noscript><link rel="stylesheet";类型=文本/css";href=https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&amp;family=Karla:wght@700&display=swap"/></noscript>

不漂亮,但比在 中包含

(所有浏览器都不能正确解释)要好.

有一个 开放 RFC 来创建一个 RawHTML组件或扩展 Fragment 以接受 dangerouslySetInnerHTML 以便这样的事情在没有黑客的情况下是可能的,但它自创建以来已经一年多了.

此外,还有对此进行了相当长的讨论以及一些不同的似乎有效的解决方案(黑客).

您可以在此处查看解决方案:https://andorratechvalley.com/

On a Next.js project, I'd like to get some initial HTML with this exact same content inside the <head>:

<link href="..." rel="stylesheet" media="print" onload="this.media='all'" />

What I have in my code, inside Next.js's <Head> component, is:

{ /* @ts-ignore */ }
<link href="..." rel="stylesheet" media="print" onload="this.media='all'" />

Without the @ts-ignore it says:

Property 'onload' does not exist on type 'DetailedHTMLProps<LinkHTMLAttributes, HTMLLinkElement>'. Did you mean 'onLoad'? ts(2322)

And if I use onLoad instead of onload I get:

Type 'string' is not assignable to type '(event: SyntheticEvent<HTMLLinkElement, Event>) => void'. ts(2322)

The problem is that the server-side generated HTML that I get has:

<link href="..." rel="stylesheet" media="print" />

And only once the page has rehydrated it updates to:

<link href="..." rel="stylesheet" media="all" onload="this.media='all'">

I've found this issue on GitHub but it doesn't help as I'm not using Google Fonts but Typography.com, so I can't use next-google-fonts: https://github.com/vercel/next.js/issues/12984

I'm thinking about adding a ref to that link tag and setting the attribute using setAttribute, which will hopefully work on the server-side as well, but wondering if there's a simpler way to do it.

解决方案

So I eventually fixed this using a <style> tag with dangerouslySetInnerHTML in a custom _document.js. All together it should look like this:

<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>

Which generates the following output:

<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin="anonymous"/>

<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;600&amp;family=Karla:wght@700&amp;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&amp;family=Karla:wght@700&amp;display=swap"/></noscript>

Not pretty, but better than having a <div> inside the <head> (which is not interpreted correctly by all browsers).

There's an open RFC to create a RawHTML component or extend Fragment to accept dangerouslySetInnerHTML so that something like this is possible without hacks, but it's been more than a year since it was created.

Also, there's quite a long discussion about this as well with a few different solutions (hacks) that seem to work.

You can see the solution working here: https://andorratechvalley.com/

这篇关于Next.js - 如何添加 &lt;link&gt;<head> 内的标签带有文字 onload 属性字符串值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆