Интеграция с Next.js Link

Chakra UI предоставляет мощный набор компонентов для построения интерфейсов на React, включая кнопку, карточку, меню и многое другое. При использовании Next.js часто возникает необходимость интеграции компонентов Chakra UI с маршрутизацией через next/link. Эта интеграция позволяет сохранить преимущества стилизованных компонентов Chakra UI, одновременно обеспечивая клиентскую навигацию Next.js, которая не перезагружает страницу.

В Chakra UI есть универсальный компонент Link, который можно комбинировать с Next.js Link для достижения плавной маршрутизации.


Базовый способ интеграции заключается в обёртывании компонента ChakraLink внутрь компонента NextLink:

import { Link as ChakraLink } from '@chakra-ui/react';
import NextLink from 'next/link';

function Example() {
  return (
    <NextLink href="/about" passHref>
      <ChakraLink color="teal.500" fontWeight="bold">
        О нас
      </ChakraLink>
    </NextLink>
  );
}

Ключевые моменты:

  • passHref — обязательный атрибут для передачи пропса href внутрь компонента ChakraLink. Без него Chakra UI не сможет корректно установить ссылку.
  • Chakra UI Link сохраняет все стили, такие как color, fontWeight, textDecoration, которые можно легко изменять.
  • Навигация происходит без полной перезагрузки страницы благодаря Next.js Link.

Создание универсального компонента ссылки

Для удобства можно создать обёртку, которая объединяет функциональность Chakra UI и Next.js Link, чтобы не писать NextLink + ChakraLink в каждом месте:

import { forwardRef } from 'react';
import { Link as ChakraLink } from '@chakra-ui/react';
import NextLink from 'next/link';

const NextChakraLink = forwardRef(({ href, children, ...props }, ref) => (
  <NextLink href={href} passHref legacyBehavior>
    <ChakraLink ref={ref} {...props}>
      {children}
    </ChakraLink>
  </NextLink>
));

export default NextChakraLink;

Преимущества:

  • Универсальность: можно использовать так же, как обычный Chakra Link.
  • Поддержка всех пропсов Chakra UI (color, fontSize, hover, focus).
  • Сокращение повторяющегося кода.

Пример использования:

import NextChakraLink from './NextChakraLink';

function Navigation() {
  return (
    <nav>
      <NextChakraLink href="/" color="blue.600" fontWeight="semibold">
        Главная
      </NextChakraLink>
      <NextChakraLink href="/blog" color="blue.600" ml={4}>
        Блог
      </NextChakraLink>
    </nav>
  );
}

Интеграция с кнопками Chakra UI

Часто требуется сделать навигацию через кнопку Chakra UI. В таком случае можно использовать свойство as:

import { Button } from '@chakra-ui/react';
import NextLink from 'next/link';

function HomeButton() {
  return (
    <Button as={NextLink} href="/home" colorScheme="teal">
      На главную
    </Button>
  );
}

Особенности:

  • Использование as={NextLink} превращает компонент Chakra UI Button в ссылку с полной поддержкой маршрутизации Next.js.
  • Пропсы Chakra UI (colorScheme, size, variant) полностью сохраняются.
  • Подходит для элементов интерфейса, которые визуально выглядят как кнопки, но логически являются ссылками.

Стилизация активных ссылок

Для навигационных меню важно подсвечивать активную ссылку. Комбинация Chakra UI и Next.js позволяет использовать хук useRouter:

import { useRouter } from 'next/router';
import { Link as ChakraLink } from '@chakra-ui/react';
import NextLink from 'next/link';

function NavLink({ href, children }) {
  const router = useRouter();
  const isActive = router.pathname === href;

  return (
    <NextLink href={href} passHref>
      <ChakraLink
        fontWeight={isActive ? 'bold' : 'normal'}
        color={isActive ? 'teal.600' : 'gray.700'}
      >
        {children}
      </ChakraLink>
    </NextLink>
  );
}

Такой подход обеспечивает:

  • Подсветку текущей страницы в навигации.
  • Поддержку стилизованных пропсов Chakra UI.
  • Гибкость для меню с произвольным количеством пунктов.

Использование с внешними ссылками

Если необходимо создавать ссылки на внешние ресурсы, Chakra UI Link можно использовать напрямую, без Next.js Link:

import { Link as ChakraLink } from '@chakra-ui/react';

function ExternalLink() {
  return (
    <ChakraLink href="https://chakra-ui.com" isExternal color="blue.500">
      Документация Chakra UI
    </ChakraLink>
  );
}
  • Атрибут isExternal добавляет rel="noopener noreferrer" и target="_blank" автоматически.
  • Сохраняются все возможности стилизации Chakra UI.

Поддержка TypeScript

При использовании TypeScript рекомендуется явно типизировать компоненты обёртки:

import { forwardRef, ReactNode } from 'react';
import { Link as ChakraLink, LinkProps as ChakraLinkProps } from '@chakra-ui/react';
import NextLink, { LinkProps as NextLinkProps } from 'next/link';

interface NextChakraLinkProps extends ChakraLinkProps, NextLinkProps {
  children: ReactNode;
}

const NextChakraLink = forwardRef<HTMLAnchorElement, NextChakraLinkProps>(
  ({ href, children, ...props }, ref) => (
    <NextLink href={href} passHref legacyBehavior>
      <ChakraLink ref={ref} {...props}>
        {children}
      </ChakraLink>
    </NextLink>
  )
);

export default NextChakraLink;

Типизация обеспечивает автодополнение и проверку пропсов Chakra UI и Next.js одновременно, что снижает риск ошибок.


Рекомендации по производительности

  • Использовать prefetch={false} в NextLink, если ссылки ведут на страницы, которые редко посещаются, чтобы не загружать лишние данные.
  • Сохранять единообразие: все внутренние ссылки в проекте лучше оформлять через одну обёртку NextChakraLink.
  • Для динамических маршрутов использовать шаблонные строки ${id} и проверку router.pathname, чтобы корректно подсвечивать активную ссылку.

Итоговые возможности интеграции

  1. Сохранение стилизации Chakra UI при клиентской навигации Next.js.
  2. Создание универсальных компонентов ссылок для всего проекта.
  3. Поддержка кнопок как ссылок через as={NextLink}.
  4. Лёгкая реализация подсветки активной страницы.
  5. Полная поддержка TypeScript и автодополнения пропсов.

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