Next.js - 如何使用文字 onload 属性字符串值在 <link> 内添加 <head> 标签?

问题描述 投票:0回答:1

在 Next.js 项目中,我想获得一些初始 HTML,其中的内容完全相同

<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
,它会说:

类型“DetailedHTMLProps”上不存在属性“onload”。您指的是“onLoad”吗? ts(2322)

如果我使用

onLoad
而不是
onload
我得到:

类型“string”不可分配给类型“(event: SyntheticEvent) => void”。 ts(2322)

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

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

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

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

我在 GitHub 上发现了这个问题,但它没有帮助,因为我没有使用 Google Fonts,而是使用 Typography.com,所以我无法使用

next-google-fonts
https://github.com/vercel/next .js/issues/12984

我正在考虑向该

ref
标签添加
link
并使用
setAttribute
设置属性,这希望也能在服务器端工作,但想知道是否有更简单的方法来做到这一点。

javascript reactjs next.js server-side-rendering head
1个回答
6
投票

更新答案(下13-14):

Next.js 现在提供开箱即用的 Google 和本地字体优化。以下是加载 Google 字体的方法:

// This will add the Inter font to your own deployment, serving 
// them from your domain without sending any data to Google:
import { Inter } from 'next/font/google';

// If loading a variable font, you don't need to specify the font weight
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  )
}

原答案(下12):

所以我最终在

自定义
<style>
中使用带有
dangerouslySetInnerHTML
_document.js
标签修复了这个问题。总而言之,它应该看起来像这样:

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

不太漂亮,但比在

<div>
中包含
<head>
更好(并非所有浏览器都能正确解释)。

有一个 open RFC 可以创建

RawHTML
组件或扩展
Fragment
来接受
dangerouslySetInnerHTML
,这样就可以在没有黑客的情况下实现类似的功能,但距离创建已经一年多了。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.