Пошук уроків, статей та іншого контенту
Побудуєте внутрішню перелінковку, яка покращує навігацію, розподіл ваги сторінок і виявлення контенту.
Внутрішня перелінковка — це система посилань між сторінками одного сайту. У Next.js такі посилання зазвичай створюють компонентом Link з next/link.
Добре спроєктована перелінковка допомагає:
користувачам переходити між пов’язаними матеріалами;
пошуковим роботам знаходити нові сторінки;
передавати внутрішню вагу між сторінками;
зрозуміти ієрархію та тематичні зв’язки контенту;
зменшити кількість «сирітських» сторінок, на які не веде жодне внутрішнє посилання.
Внутрішнє посилання не гарантує вищих позицій у пошуку. Воно є одним із сигналів, який допомагає пошуковику зрозуміти структуру сайту та важливість його сторінок.
LinkДля внутрішніх переходів використовуйте Link:
import Link from "next/link";
export default function HomePage() {
return (
<main>
<h1>Блог про веброзробку</h1>
<Link href="/articles">
Переглянути всі статті
</Link>
</main>
);
}Link створює звичайне HTML-посилання, але Next.js може оптимізувати перехід між сторінками без повного перезавантаження документа.
Для внутрішніх маршрутів використовуйте шляхи:
<Link href="/articles">Статті</Link>
<Link href="/articles/nextjs-routing">Маршрутизація в Next.js</Link>Не потрібно використовувати повну адресу сайту:
// Зайве для внутрішнього переходу
<a href="https://example.com/articles">Статті</a>Для зовнішніх сайтів звичайний a є правильним вибором:
<a href="https://nextjs.org" target="_blank" rel="noreferrer">
Документація Next.js
</a>Перед реалізацією визначте логіку переходів між сторінками. Наприклад, для блогу можна використати таку структуру:
головна сторінка веде до основних розділів;
сторінка розділу веде до всіх статей цього розділу;
сторінка статті веде до батьківського розділу;
стаття містить посилання на пов’язані матеріали;
навігація або хлібні крихти допомагають повернутися на вищий рівень.
Це створює тематичні кластери. Сторінка розділу стає центральною точкою, а окремі статті пов’язуються між собою.
/
├── articles
│ ├── nextjs-routing
│ ├── nextjs-metadata
│ └── internal-linking
└── aboutУ такій структурі сторінка /articles є хабом для статей, а окремі матеріали мають зрозумілі URL.
Нижче наведено спрощений блог на Next.js App Router.
Файл lib/articles.ts:
export type Article = {
slug: string;
title: string;
category: string;
excerpt: string;
body: string;
relatedSlugs: string[];
};
export const articles: Article[] = [
{
slug: "nextjs-routing",
title: "Маршрутизація в Next.js",
category: "Next.js",
excerpt: "Як організувати маршрути в App Router.",
body: "App Router використовує файлову структуру для побудови маршрутів.",
relatedSlugs: ["nextjs-metadata", "internal-linking"],
},
{
slug: "nextjs-metadata",
title: "Метадані сторінок у Next.js",
category: "Next.js",
excerpt: "Як додавати заголовки та описи сторінок.",
body: "Метадані допомагають описати сторінку для браузера та пошукових систем.",
relatedSlugs: ["nextjs-routing", "internal-linking"],
},
{
slug: "internal-linking",
title: "Внутрішня перелінковка",
category: "SEO",
excerpt: "Як пов’язувати сторінки сайту між собою.",
body: "Внутрішні посилання допомагають користувачам і пошуковим роботам переходити між пов’язаними сторінками.",
relatedSlugs: ["nextjs-routing", "nextjs-metadata"],
},
];
export function getArticleBySlug(slug: string) {
return articles.find((article) => article.slug === slug);
}Файл app/page.tsx:
import Link from "next/link";
export default function HomePage() {
return (
<main>
<h1>Блог про веброзробку</h1>
<p>
Практичні матеріали про Next.js, маршрутизацію та SEO.
</p>
<nav aria-label="Основна навігація">
<ul>
<li>
<Link href="/articles">Усі статті</Link>
</li>
<li>
<Link href="/about">Про сайт</Link>
</li>
</ul>
</nav>
</main>
);
}Головна сторінка містить посилання на основні розділи. Завдяки цьому сторінка статей доступна як користувачам, так і пошуковим роботам.
Файл app/articles/page.tsx:
import Link from "next/link";
import { articles } from "@/lib/articles";
export default function ArticlesPage() {
return (
<main>
<nav aria-label="Хлібні крихти">
<Link href="/">Головна</Link>
</nav>
<h1>Усі статті</h1>
<ul>
{articles.map((article) => (
<li key={article.slug}>
<article>
<h2>
<Link href={`/articles/${article.slug}`}>
{article.title}
</Link>
</h2>
<p>{article.excerpt}</p>
<Link href={`/articles/${article.slug}`}>
Читати статтю «{article.title}»
</Link>
</article>
</li>
))}
</ul>
</main>
);
}Тут кожна стаття має:
унікальний URL;
зрозумілий текст посилання;
посилання із заголовка;
додаткове посилання з описовим текстом.
У реальному проєкті не завжди потрібно додавати два посилання на одну й ту саму сторінку в кожній картці. Часто достатньо посилання із заголовка або кнопки.
Файл app/articles/[slug]/page.tsx:
import Link from "next/link";
import { notFound } from "next/navigation";
import { articles, getArticleBySlug } from "@/lib/articles";
type ArticlePageProps = {
params: Promise<{
slug: string;
}>;
};
export function generateStaticParams() {
return articles.map((article) => ({
slug: article.slug,
}));
}
export default async function ArticlePage({
params,
}: ArticlePageProps) {
const { slug } = await params;
const article = getArticleBySlug(slug);
if (!article) {
notFound();
}
const relatedArticles = article.relatedSlugs
.map((relatedSlug) => getArticleBySlug(relatedSlug))
.filter((relatedArticle) => relatedArticle !== undefined);
return (
<main>
<nav aria-label="Хлібні крихти">
<Link href="/">Головна</Link>
<span aria-hidden="true"> / </span>
<Link href="/articles">Статті</Link>
<span aria-hidden="true"> / </span>
<span>{article.title}</span>
</nav>
<article>
<p>{article.category}</p>
<h1>{article.title}</h1>
<p>{article.body}</p>
</article>
{relatedArticles.length > 0 && (
<aside>
<h2>Пов’язані статті</h2>
<ul>
{relatedArticles.map((relatedArticle) => (
<li key={relatedArticle.slug}>
<Link href={`/articles/${relatedArticle.slug}`}>
{relatedArticle.title}
</Link>
</li>
))}
</ul>
</aside>
)}
</main>
);
}У цьому прикладі одна сторінка має кілька типів внутрішніх посилань:
посилання на головну сторінку;
посилання на сторінку всіх статей;
посилання на пов’язані матеріали.
Так користувач може перейти не лише до наступної статті, а й повернутися до вищого рівня структури.
Текст посилання має пояснювати, що відкриється після переходу.
Невдалий варіант:
<Link href="/articles/nextjs-routing">Детальніше</Link>Такий текст не описує сторінку без навколишнього контексту.
Кращий варіант:
<Link href="/articles/nextjs-routing">
Дізнатися більше про маршрутизацію в Next.js
</Link>Або:
<h2>
<Link href="/articles/nextjs-routing">
Маршрутизація в Next.js
</Link>
</h2>Описовий текст корисний для:
доступності;
швидкого сканування сторінки користувачем;
розуміння зв’язку між сторінками пошуковими системами.
Не потрібно штучно повторювати однакове ключове слово в кожному посиланні. Текст має бути природним і відповідати змісту цільової сторінки.
Хлібні крихти показують поточне розташування сторінки в ієрархії сайту.
<nav aria-label="Хлібні крихти">
<Link href="/">Головна</Link>
<span aria-hidden="true"> / </span>
<Link href="/articles">Статті</Link>
<span aria-hidden="true"> / </span>
<span aria-current="page">Маршрутизація в Next.js</span>
</nav>Важливо:
використовувати nav для навігаційного блоку;
додавати aria-label, щоб пояснити призначення навігації;
поточну сторінку не робити посиланням без потреби;
кожен попередній рівень робити доступним для переходу.
Хлібні крихти особливо корисні для глибоких структур, де сторінка знаходиться на кількох рівнях вкладеності.
Пошукові роботи можуть знаходити сторінки через посилання з атрибутом href. Тому важлива не лише наявність сторінки в коді, а й її доступність через навігацію сайту.
Сторінка може стати «сиротою», якщо:
на неї немає посилань з інших сторінок;
вона доступна лише через пошук або фільтр;
посилання на неї створюється тільки після дії JavaScript, яку робот не виконує;
URL є помилковим або містить непередбачуваний ідентифікатор.
Для важливих сторінок перевірте, що користувач може дістатися до них за кілька переходів:
Головна → Статті → Категорія → СтаттяНе обов’язково вести посилання на кожну сторінку безпосередньо з головної. Достатньо логічної та доступної структури.
Кількість і розташування внутрішніх посилань допомагають показати відносну важливість сторінок.
Наприклад:
сторінка «Основи Next.js» може бути центральним матеріалом;
з неї можна послатися на маршрутизацію, метадані та оптимізацію;
кожен дочірній матеріал може повертати посилання на центральний матеріал;
сторінка списку статей об’єднує всі матеріали розділу.
Це створює двонапрямлений тематичний зв’язок:
Центральна стаття
├── Маршрутизація
├── Метадані
└── Внутрішня перелінковкаНе потрібно додавати сотні посилань на кожну сторінку. Надлишкова кількість посилань:
ускладнює навігацію;
зменшує помітність важливих переходів;
може виглядати неприродно;
збільшує візуальне навантаження на сторінку.
Додавайте посилання там, де вони справді допомагають продовжити читання або зрозуміти тему.
У App Router компонент Link можна використовувати без перетворення сторінки на Client Component:
import Link from "next/link";
export default function Navigation() {
return (
<nav>
<Link href="/articles">Статті</Link>
</nav>
);
}Це зручно для навігації, яка не потребує стану браузера чи обробників подій.
Для динамічних URL використовуйте шаблонні рядки:
const slug = "nextjs-routing";
<Link href={`/articles/${slug}`}>
Маршрутизація в Next.js
</Link>Переконайтеся, що значення slug відповідає маршруту та коректно обробляється на сторінці. Якщо стаття не знайдена, використовуйте notFound() замість рендерингу порожньої сторінки.
Складіть список важливих сторінок.
Об’єднайте їх за темами та розділами.
Створіть сторінки-хаби для основних категорій.
Додайте посилання зі списків на окремі матеріали.
Додайте посилання на батьківський розділ зі сторінок матеріалів.
Пов’яжіть тематично близькі сторінки блоком «Пов’язані матеріали».
Перевірте, що важливі сторінки не залишилися без вхідних посилань.
Замініть загальні тексти на описові.
Видаліть посилання, які не допомагають навігації або розумінню теми.
a замість Link для внутрішніх маршрутів<a href="/articles">Статті</a>Такий код може працювати, але для внутрішньої навігації в Next.js зазвичай варто використовувати Link.
<Link href="/articles">Статті</Link><Link href="/articles/nextjs-metadata">Перейти</Link>Краще:
<Link href="/articles/nextjs-metadata">
Метадані сторінок у Next.js
</Link>Помилка в href призводить до переходів на сторінку 404:
<Link href="/article/nextjs-routing">
Маршрутизація
</Link>Якщо фактичний маршрут — /articles/[slug], правильний URL буде таким:
<Link href="/articles/nextjs-routing">
Маршрутизація
</Link>Якщо зі сторінки статті немає способу повернутися до списку матеріалів, користувач змушений використовувати кнопку браузера або головне меню.
Додавайте хлібні крихти, посилання на категорію або інший зрозумілий шлях назад.
Не потрібно посилатися на всі сторінки сайту з кожного матеріалу. Вибирайте лише тематично пов’язані та корисні переходи.
Важливий контент не повинен бути доступним тільки після натискання кнопки, відкриття меню або виконання пошуку. Для ключових сторінок створюйте звичайні видимі посилання в навігації чи тексті.
Для кожного важливого маршруту перевірте:
чи є на нього хоча б одне внутрішнє посилання;
чи веде href до правильного URL;
чи немає посилань на 404;
чи зрозумілий текст посилання;
чи можна повернутися до батьківського розділу;
чи пов’язані між собою сторінки однієї теми;
чи не містить сторінка зайвої кількості повторюваних посилань.
Зручний спосіб перевірки — пройти сайт як користувач: почати з головної сторінки та спробувати дістатися кожного важливого матеріалу без введення URL вручну.
Для внутрішніх переходів у Next.js використовуйте Link з next/link.
Формуйте перелінковку як логічну структуру: головна сторінка, розділи, статті та пов’язані матеріали.
Використовуйте описові тексти посилань замість загальних «Детальніше» або «Перейти».
Додавайте хлібні крихти для навігації в глибоких розділах.
Переконайтеся, що важливі сторінки не є «сиротами».
Пов’язуйте тематично близькі матеріали, але не створюйте надмірну кількість посилань.
Перевіряйте URL, доступність маршрутів і переходи до батьківських розділів.