Перейти к содержанию

<link>

Canary

Расширения React для <link> в настоящее время доступны только в канале React canary и экспериментальном канале. В стабильных релизах React <link> работает только как встроенный в браузер HTML-компонент. Подробнее о каналах выпуска React здесь.

Встроенный компонент браузера <link> позволяет использовать внешние ресурсы, такие как таблицы стилей, или аннотировать документ метаданными ссылок.

1
<link rel="icon" href="favicon.ico" />

Описание

Чтобы сделать ссылки на внешние ресурсы, такие как таблицы стилей, шрифты и иконки, или аннотировать документ метаданными ссылок, используйте встроенный в браузер компонент <link>. Вы можете рендерить <link> из любого компонента, и React в большинстве случаев поместит соответствующий элемент DOM в голову документа.

1
<link rel="icon" href="favicon.ico" />

Параметры

<link> поддерживает все общие пропсы элементов

Эти реквизиты применяются, когда rel="stylesheet":

  • precedence: строка. Указывает React, где ранжировать DOM-узел <link> относительно других в документе <head>, что определяет, какая таблица стилей может перекрыть другую. Его значение может быть (в порядке старшинства) " reset", "low", "medium", "high". Таблицы стилей с одинаковым старшинством идут вместе независимо от того, являются ли они тегами <link> или встроенными тегами <style> или загружаются с помощью функций preload или preinit.
  • media: строка. Ограничивает электронную таблицу определенным media query.
  • title: строка. Задает имя альтернативной таблицы стилей.

Эти реквизиты применяются, когда rel="stylesheet", но отключают особое отношение React к таблицам стилей:

  • disabled: булево. Отключает таблицу.
  • onError: функция. Вызывается, когда таблица стилей не загружается.
  • onLoad: функция. Вызывается, когда таблица стилей завершает загрузку.

Эти реквизиты применяются, когда rel="preload" или rel="modulepreload":

  • as: строка. Тип ресурса. Возможные значения: audio, document, embed, fetch, font, image, object, script, style, track, video, worker.
  • imageSrcSet: строка. Применяется только в случае as="image". Указывает исходный набор изображения.
  • imageSizes: строка. Применяется только в случае as="image". Указывает размеры изображения.

Этот реквизит применяется при rel="icon" или rel="apple-touch-icon":

Эти параметры применяются во всех случаях:

  • href: строка. URL-адрес связанного ресурса.
  • crossOrigin: строка. Используемая политика CORS. Возможные значения: anonymous и use-credentials. Требуется, если для параметра as установлено значение "fetch".
  • referrerPolicy: строка. Заголовок Referrer header, который следует отправлять при выборке. Возможные значения: no-referrer-when-downgrade (по умолчанию), no-referrer, origin, origin-when-cross-origin, и unsafe-url.
  • fetchPriority: строка. Указывает относительный приоритет для получения ресурса. Возможные значения: auto (по умолчанию), high и low.
  • hrefLang: строка. Язык связанного ресурса.
  • integrity: строка. Криптографический хэш ресурса для проверки его подлинности.
  • type: строка. MIME-тип связанного ресурса.

Реквизиты, которые не рекомендуется использовать с React:

  • blocking: строка. Если установлено значение "render", это указывает браузеру не рендерить страницу до тех пор, пока не будет загружена таблица стилей. React обеспечивает более тонкий контроль с помощью Suspense.

Особое поведение рендеринга

React всегда будет помещать элемент DOM, соответствующий компоненту <link>, в <head> документа, независимо от того, в каком месте дерева React он отрисовывается. <head> - единственное допустимое место для <link> в DOM, но это удобно и позволяет сохранить композитность, если компонент, представляющий определенную страницу, может сам рендерить компоненты <link>.

Из этого есть несколько исключений:

  • Если у <link> есть свойство rel="stylesheet", то для получения такого особого поведения у него также должно быть свойство precedence. Это происходит потому, что порядок следования таблиц стилей в документе имеет значение, поэтому React должен знать, как упорядочить эту таблицу стилей относительно других, которые вы указываете с помощью свойства precedence. Если параметр precedence опущен, то никакого особого поведения не будет.
  • Если у <link> есть реквизит itemProp, то никакого особого поведения не будет, потому что в этом случае она не относится к документу, а представляет собой метаданные о конкретной части страницы.
  • Если у <link> есть свойство onLoad или onError, то в этом случае вы управляете загрузкой связанного ресурса вручную внутри вашего компонента React.

Особое поведение для таблиц стилей

Кроме того, если <link> является ссылкой на таблицу стилей (а именно, имеет rel="stylesheet" в своем реквизите), React обрабатывает ее особым образом следующим образом:

  • Компонент, отображающий <link>, будет приостановлен на время загрузки таблицы стилей.
  • Если несколько компонентов отображают ссылки на одну и ту же таблицу стилей, React будет дедублировать их и помещать в DOM только одну ссылку. Две ссылки считаются одинаковыми, если у них одинаковый параметр href.

Есть два исключения из этого особого поведения:

  • Если у ссылки нет свойства precedence, то особого поведения не будет, потому что порядок следования таблиц стилей в документе имеет значение, поэтому React должен знать, как упорядочить эту таблицу стилей относительно других, что вы и указываете с помощью свойства precedence.
  • Если вы предоставите любой из реквизитов onLoad, onError или disabled, то никакого особого поведения не будет, потому что эти реквизиты указывают на то, что вы управляете загрузкой таблицы стилей вручную внутри вашего компонента.

Это особое отношение сопровождается двумя оговорками:

  • React будет игнорировать изменения реквизитов после того, как ссылка будет отрисована. (Если это произойдет, React выдаст предупреждение в процессе разработки).
  • React может оставить ссылку в DOM даже после того, как компонент, который ее отобразил, будет размонтирован.

Использование

Вы можете аннотировать документ ссылками на связанные ресурсы, такие как иконка, канонический URL или pingback. React поместит эти метаданные в <head> документа, независимо от того, в каком месте дерева React он будет отображаться.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function BlogPage() {
    return (
        <ShowRenderedHTML>
            <link rel="icon" href="favicon.ico" />
            <link
                rel="pingback"
                href="http://www.example.com/xmlrpc.php"
            />
            <h1>My Blog</h1>
            <p>...</p>
        </ShowRenderedHTML>
    );
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { renderToStaticMarkup } from 'react-dom/server';
import formatHTML from './formatHTML.js';

export default function ShowRenderedHTML({ children }) {
    const markup = renderToStaticMarkup(
        <html>
            <head />
            <body>{children}</body>
        </html>
    );
    return (
        <>
            <h1>Rendered HTML:</h1>
            <pre>{formatHTML(markup)}</pre>
        </>
    );
}

Ссылка на таблицу стилей

Если компонент зависит от определенной таблицы стилей для корректного отображения, вы можете отобразить ссылку на эту таблицу стилей внутри компонента. Ваш компонент будет приостановлен на время загрузки таблицы стилей. Вы должны указать параметр precedence, который указывает React, куда поместить эту таблицу стилей относительно других - таблицы стилей с более высоким приоритетом могут перекрывать таблицы с более низким приоритетом.

Когда вы хотите использовать таблицу стилей, может быть полезно вызвать функцию preinit. Вызов этой функции может позволить браузеру начать поиск таблицы стилей раньше, чем если бы вы просто отобразили компонент <link>, например, отправив ответ HTTP Early Hints response.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function SiteMapPage() {
    return (
        <ShowRenderedHTML>
            <link
                rel="stylesheet"
                href="sitemap.css"
                precedence="medium"
            />
            <p>...</p>
        </ShowRenderedHTML>
    );
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { renderToStaticMarkup } from 'react-dom/server';
import formatHTML from './formatHTML.js';

export default function ShowRenderedHTML({ children }) {
    const markup = renderToStaticMarkup(
        <html>
            <head />
            <body>{children}</body>
        </html>
    );
    return (
        <>
            <h1>Rendered HTML:</h1>
            <pre>{formatHTML(markup)}</pre>
        </>
    );
}

Управление приоритетом таблиц стилей

Таблицы стилей могут конфликтовать друг с другом, и когда это происходит, браузер выбирает ту, которая находится позже в документе. React позволяет управлять порядком следования таблиц стилей с помощью свойства precedence. В этом примере два компонента рендерят таблицы стилей, и та, что имеет больший приоритет, идет позже в документе, хотя компонент, который ее рендерит, идет раньше.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function HomePage() {
    return (
        <ShowRenderedHTML>
            <FirstComponent />
            <SecondComponent />
            ...
        </ShowRenderedHTML>
    );
}

function FirstComponent() {
    return (
        <link
            rel="stylesheet"
            href="first.css"
            precedence="high"
        />
    );
}

function SecondComponent() {
    return (
        <link
            rel="stylesheet"
            href="second.css"
            precedence="low"
        />
    );
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { renderToStaticMarkup } from 'react-dom/server';
import formatHTML from './formatHTML.js';

export default function ShowRenderedHTML({ children }) {
    const markup = renderToStaticMarkup(
        <html>
            <head />
            <body>{children}</body>
        </html>
    );
    return (
        <>
            <h1>Rendered HTML:</h1>
            <pre>{formatHTML(markup)}</pre>
        </>
    );
}

Дублированный рендеринг таблицы стилей

Если вы рендерите одну и ту же таблицу стилей из нескольких компонентов, React поместит только одну <link> в шапку документа.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function HomePage() {
    return (
        <ShowRenderedHTML>
            <Component />
            <Component />
            ...
        </ShowRenderedHTML>
    );
}

function Component() {
    return (
        <link
            rel="stylesheet"
            href="styles.css"
            precedence="medium"
        />
    );
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { renderToStaticMarkup } from 'react-dom/server';
import formatHTML from './formatHTML.js';

export default function ShowRenderedHTML({ children }) {
    const markup = renderToStaticMarkup(
        <html>
            <head />
            <body>{children}</body>
        </html>
    );
    return (
        <>
            <h1>Rendered HTML:</h1>
            <pre>{formatHTML(markup)}</pre>
        </>
    );
}

Вы можете использовать компонент <link> с параметром itemProp для аннотирования определенных элементов в документе ссылками на связанные ресурсы. В этом случае React не будет размещать эти аннотации внутри документа <head>, а разместит их как любой другой компонент React.

1
2
3
4
5
<section itemScope>
    <h3>Annotating specific items</h3>
    <link itemProp="author" href="http://example.com/" />
    <p>...</p>
</section>

Источник — https://react.dev/reference/react-dom/components/link

Комментарии