Как добавить значок на статический сайт Next.js?

Я безуспешно пытаюсь добавить значок на статический сайт Next.js.

Я пытался настроить документ с помощью компонентов из 'next/document'https://nextjs.org/docs/#пользовательский-документ

Прямая ссылка на файл favicon.ico не работает, потому что файл не включен в сборку и href не обновляется до /_next/static/...

Импорт изображения и добавление в 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>
    );
  }
}

Ссылки на фавикон добавляются, но не отображаются. Я ожидал, что это сработает, когда я импортирую файл, но он просто добавляет ссылку <link rel = "shortcut icon" href = "[object Object]">.

Кто-нибудь сделал это еще?


56
83 142
8

Ответы:

Решено
  1. Создайте папку /static в корне проекта. Это будет добавлено в папку статического экспорта.
  2. Добавьте файл favicon в папку /static.
  3. Добавьте _document.js в папку /pages/ в соответствии с документация (nextjs.org) или документация (github.com).
  4. Добавьте <link rel = "shortcut icon" href = "/static/favicon.ico" /> к голове.
  5. npm run build && npm run export

P.S. Благодаря предыдущий ответ, который был удален. Оно работает!


Редактировать: Другой способ сделать это — добавить импорт головы в корневой макет и добавить туда ссылку. Все, что добавляется к Голова, вставляется в тег заголовка документа.

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;

Обновлять :

Статический каталог устарел в пользу общего каталога. Док

Итак, теперь код будет выглядеть так

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буквально в любом месте (см. документы)

Так что я закончил с _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 в общую папку, Next js автоматически возьмет этот значок для всех страниц.

Не нужно добавлять ссылку на фавикон на какие-либо страницы или в тег, не нужно добавлять ссылку на фавикон.

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


Просто добавить файл .ico недостаточно.

Добавьте теги ссылок в раздел <Head> в _document.jsx или _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 и загружать результаты в папку /public/favicons/. На эту папку можно ссылаться /favicons/ из-за характера публичный каталог.


По состоянию на июнь 2020 года вам не нужно добавлять/редактировать файлы document.js или _head.js. Все, что вам нужно сделать, это поместить файл favicon.ico в общедоступный каталог, и все.


В моем случае это НЕ РАБОТАЕТ БЕЗ ИМПОРТ:

файл: _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>

Для меня он отсутствовал на рабочем сайте, но отлично работал на локальном, потому что я не добавлял общую папку в артефакты рабочего сайта. Я предполагал, что 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