如何将网站图标添加到 Next.js 静态站点?

How to add a favicon to a Next.js static site?

我正在尝试将网站图标添加到 Next.js 静态站点,但运气不佳。

我尝试使用 'next/document' 中的组件自定义文档 https://nextjs.org/docs/#custom-document

link 到 favicon.ico 文件的直接 link 不起作用,因为该文件未包含在构建中并且 href 未更新为 /_next/static/...

导入图像并添加到 link 的 href 也不起作用(参见注释掉的行)。

import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';

// import favicon from '../data/imageExports';

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <Head>
          {/* <link rel="shortcut icon" href={favicon} /> */}
          <link rel="shortcut icon" href="../images/icons/favicon.ico" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

favicon links 已添加,但它不显示。 我希望它在我导入文件时工作,但它只是添加了一个<link rel="shortcut icon" href="[object Object]"> link.

有人做过吗?

  1. 在项目根目录中创建一个 /static 文件夹。这将被添加到静态导出文件夹。
  2. /static 文件夹中添加图标文件。
  3. 根据 documentation (nextjs.org) or documentation (github.com) 添加 _document.js/pages/ 文件夹。
  4. <link rel="shortcut icon" href="/static/favicon.ico" /> 添加到标题。
  5. npm run build && npm run export

P.S。感谢删除的previous answer。有效!


编辑:另一种方法是 将 Head 导入到您的根布局中,然后在其中添加 link。添加到 Head 的任何内容都会插入到文档头部标记中。

import Head from 'next/head';

const Page = (props) => (
  <div>
    <Head>
      <link rel="shortcut icon" href="/static/favicon.ico" />
    </Head>
    // Other layout/components
  </div>
);

export default Page;

更新:

静态目录已被弃用,取而代之的是 public 目录。 Doc

所以,代码现在看起来像

import Head from 'next/head';

const Page = (props) => (
  <div>
    <Head>
      <link rel="shortcut icon" href="/favicon.ico" />
    </Head>
    // Other layout/components
  </div>
);

接受的答案很好,但可能值得指出的是您没有修改_document.js以添加网站图标(也没有添加任何标签)至 head).

我自己发现将网站图标放在 _app.js 中更有意义。这个文件很可能已经存在,用于设置页面布局或类似的东西。您可以在任何地方添加 Head 标签 (参见 the docs

所以我得到了 _app.js

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;

    return (
      <Layout>
        <Head>
          <link rel="shortcut icon" href="/favicon.ico" />
        </Head>
        <Component {...pageProps} />
      </Layout>
    );
  }
}

只需将您的 favicon.ico 添加到 public 文件夹中, 接下来 js 将自动为所有页面使用该图标。

无需在任何页面或标签中添加任何图标 link 无需为图标添加 link。

https://github.com/zeit/next.js/blob/master/errors/static-dir-deprecated.md

只添加.ico文件是不够的。

Add link tags to <Head> section in _document.jsx or _document.tsx 问题只是关于 .ico 文件,但我建议添加不同的维度和格式以获得更好的支持。

import React from 'react';
import Document, { Html, Head, Main, NextScript, DocumentContext, DocumentInitialProps } from 'next/document';

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render(): React.ReactElement {
    return (
      <Html>
        <Head>
          <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
          <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
          <link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
          <link rel="manifest" href="/favicons/site.webmanifest" />
          <link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5" />
          <meta name="msapplication-TileColor" content="#ffc40d" />
          <meta name="theme-color" content="#ffffff" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

您可以使用 RealFaviconGenerator and upload results to /public/favicons/ folder. This folder can be referenced by /favicons/ due to nature of public directory 生成不同的图标。

自 2020 年 6 月起,您不必 add/edit document.js_head.js 文件。您只需将 favicon.ico 文件放入 public 目录即可。

在我的例子中,没有导入就无法工作:

文件:_app.tsx


    import { AppContext, AppProps } from "next/app";
    import "../styles/common.scss";
    import Head from 'next/head';
    //For me it didn't work without the following import...
    import favico from "../static/favicon.ico";
    
    
    function MyApp({ Component, pageProps }: AppProps) {
      const csrfToken = pageProps["anti-csrftoken-a2z"];
      return (
        <div>
          <Head>
            <link rel="shortcut icon" href={favico} type="image/x-icon" />
          </Head>
          <Component {...pageProps} />
        </div>
      );
    }
    
    MyApp.getInitialProps = async ({ Component, ctx }: AppContext) => {
      let pageProps = {};
      if (Component.getInitialProps) {
        pageProps = await Component.getInitialProps(ctx);
      }
      return { pageProps };
    };
    
    export default MyApp;

我认为这对某人有用

<Head>
    <link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-touch-icon-57x57.png" />
    <link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-touch-icon-60x60.png" />
    <link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-touch-icon-72x72.png" />
    <link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-touch-icon-76x76.png" />

    <link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-touch-icon-114x114.png" />
    <link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-touch-icon-120x120.png" />
    <link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-touch-icon-144x144.png" />
    <link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-touch-icon-152x152.png" />
    <link rel="apple-touch-icon" sizes="167x167" href="/favicons/apple-touch-icon-167x167.png" />
    <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon-180x180.png" />

    <link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png" />
    <link rel="icon" type="image/png" sizes="128x128" href="/favicons/favicon-128x128.png" />
    <link rel="icon" type="image/png" sizes="196x196" href="/favicons/favicon-196x196.png" />
    <link rel="icon" type="image/png" sizes="192x192" href="/favicons/android-chrome-192x192.png" />
    <link rel="icon" type="image/png" sizes="512x512" href="/favicons/android-chrome-512x512.png" />

    <link rel="shortcut icon" href="/favicons/favicon.ico" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="mobile-web-app-capable" content="yes" />

    <meta name="msapplication-TileImage" content="/favicons/mstile-144x144.png"/>
    <meta name="msapplication-square70x70logo" content="/favicons/mstile-70x70.png"/>
    <meta name="msapplication-square150x150logo" content="/favicons/mstile-150x150.png"/>
    <meta name="msapplication-square144x144logo" content="/favicons/mstile-144x144.png"/>
    <meta name="msapplication-square310x310logo" content="/favicons/mstile-310x310.png"/>
</Head>

对我来说,它在生产站点中丢失但在本地工作正常,因为我没有在生产站点的工件中添加 public 文件夹。我以为 next.js 会把所有需要的东西都放在 .next 文件夹中,但事实并非如此。

cp -R ./.next/ artifacts/
cp -R ./node_modules/ artifacts
cp -R ./public/ artifacts  #missing line in my github action code
cp package.json ./artifacts/package.json