Remix специфика

Для начала необходимо установить основные пакеты Chakra UI и их зависимости:

npm install @chakra-ui/react @emotion/react @emotion/styled framer-motion

В Remix проекте структура отличается от обычного React-приложения, поэтому важно правильно настроить провайдеры. Все компоненты Chakra UI должны быть обернуты в ChakraProvider в корневом компоненте приложения. В Remix это обычно делается в файле root.tsx:

import { ChakraProvider } from '@chakra-ui/react';
import type { LinksFunction, LoaderArgs } from '@remix-run/node';
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';

export default function App() {
  return (
    <ChakraProvider>
      <html lang="en">
        <head>
          <Meta />
          <Links />
        </head>
        <body>
          <Outlet />
          <ScrollRestoration />
          <Scripts />
          <LiveReload />
        </body>
      </html>
    </ChakraProvider>
  );
}

Ключевой момент — ChakraProvider должен быть верхним компонентом, чтобы все темы и стили корректно применялись ко всем страницам.


Работа с темизацией и настройкой темы

Chakra UI предоставляет возможность полностью настраивать тему приложения через объект extendTheme. В Remix это особенно важно для обеспечения единообразия на разных страницах. Пример расширенной темы:

import { extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  colors: {
    brand: {
      50: "#e3f2f9",
      100: "#c5e4f3",
      200: "#a2d4ec",
      300: "#7ac1e4",
      400: "#47a9da",
      500: "#0088cc",
      600: "#007ab8",
      700: "#006ba1",
      800: "#005885",
      900: "#003f5e",
    },
  },
  fonts: {
    heading: "Inter, sans-serif",
    body: "Inter, sans-serif",
  },
  components: {
    Button: {
      baseStyle: {
        fontWeight: "bold",
      },
      sizes: {
        xl: {
          h: 12,
          fontSize: "lg",
        },
      },
      variants: {
        solid: {
          bg: "brand.500",
          color: "white",
          _hover: {
            bg: "brand.600",
          },
        },
      },
    },
  },
});

export default theme;

В root.tsx необходимо передать эту тему в ChakraProvider:

<ChakraProvider theme={theme}>
  <Outlet />
</ChakraProvider>

Особенности работы с Remix и серверным рендерингом (SSR)

Remix поддерживает SSR по умолчанию, что требует особого внимания к Chakra UI. По умолчанию стили Chakra UI генерируются на клиенте, но для SSR необходимо добавить поддержку вставки стилей на сервере. Используется ServerStyleContext и ClientStyleContext. Пример настройки можно сделать через кастомные хуки и провайдеры, обеспечивающие корректный рендеринг стилей при первом загрузочном HTML.

Простейший способ — использовать встроенную поддержку через <ChakraProvider resetCSS> и <ColorModeScript initialColorMode={theme.config.initialColorMode} />:

import { ColorModeScript } from '@chakra-ui/react';
import theme from './theme';

<body>
  <ColorModeScript initialColorMode={theme.config.initialColorMode} />
  <Outlet />
</body>

Это гарантирует, что цветовая схема (light или dark) будет корректно синхронизирована на клиенте и сервере без мерцания при загрузке.


Работа с ColorMode в Remix

Chakra UI использует useColorMode для динамического переключения между светлой и тёмной темами. В Remix нужно учитывать SSR: хук нельзя использовать напрямую в коде, который выполняется на сервере. Для безопасного доступа применяется проверка typeof window !== "undefined":

import { useColorMode, Button } from '@chakra-ui/react';

function ThemeToggle() {
  const { colorMode, toggleColorMode } = useColorMode();

  if (typeof window === "undefined") return null;

  return (
    <Button onCl ick={toggleColorMode}>
      Switch to {colorMode === "light" ? "dark" : "light"} mode
    </Button>
  );
}

Для глобальной поддержки предпочтений пользователя удобно использовать cookie для сохранения выбранного режима, что полностью совместимо с Remix loader-ами.


Особенности использования компонентов Chakra UI с формами в Remix

Remix активно работает с серверными формами, поэтому важно корректно использовать Chakra UI компоненты внутри <Form>:

import { Form, useActionData } from '@remix-run/react';
import { Input, Button, FormControl, FormLabel, FormErrorMessage } from '@chakra-ui/react';

export default function ContactForm() {
  const actionData = useActionData();

  return (
    <Form method="post">
      <FormControl isInvalid={actionData?.errors?.email}>
        <FormLabel htmlFor="email">Email</FormLabel>
        <Input id="email" name="email" type="email" />
        <FormErrorMessage>{actionData?.errors?.email}</FormErrorMessage>
      </FormControl>
      <Button type="submit" mt={4} colorScheme="brand">Submit</Button>
    </Form>
  );
}

Ключевой момент — FormControl автоматически связывает ошибки с компонентом, что упрощает работу с серверными проверками Remix.


Оптимизация Chakra UI для Remix

  1. Tree-shaking компонентов – импортировать только необходимые элементы:
import { Button } from '@chakra-ui/react';
  1. Минимизация CSS – для больших приложений рекомендуется использовать emotion с SSR и правильно настраивать @emotion/server для генерации критических стилей.

  2. Lazy loading – компоненты Chakra UI можно загружать динамически с помощью React.lazy и Suspense, что особенно полезно для больших страниц с множеством UI-элементов.


Рекомендации по организации проекта

  • root.tsx — глобальные провайдеры Chakra UI и ColorModeScript.
  • theme.ts — централизованная кастомизация темы.
  • components/ — переиспользуемые Chakra UI компоненты.
  • routes/ — страницы Remix, использующие Chakra UI без прямой зависимости от клиента для SSR.

Такой подход позволяет полностью использовать преимущества Chakra UI и Remix, сохраняя высокую производительность, корректный SSR и лёгкость кастомизации интерфейсов.