ValyroUI English version

Начало работы: TanStack Start

SSR на Vite: стили — ссылкой в head() корневого маршрута, тема — на <html> в shellComponent, поэтому первая отрисовка уже в теме

1. Создайте приложение

Флаг --blank даёт минимальный шаблон. В полном шаблоне есть свой скрипт темы: он пишет data-theme="light|dark" на <html> и конфликтует с темой ValyroUI — его пришлось бы удалять. Проверено с TanStack Start 1.169.

npx @tanstack/cli@latest create my-app --framework React --blank --package-manager npm --no-git --no-intent --no-toolchain --non-interactive
cd my-app

2. Установите пакет

Подходят react и react-dom 17, 18 и 19 (на React 17 id из useId появляются сразу после монтирования). Пакет — ES-модули (плюс CommonJS-копия для require()), без runtime-зависимостей, по файлу на модуль: в бандл попадают только импортированные компоненты, а как грузить и CSS только их — в разделе «Только нужный CSS» ниже. Шрифты — отдельные файлы: тема vercel (по умолчанию в ThemeProvider) использует Geist, поэтому рядом со стилями импортируйте valyro-ui/fonts/geist.css и valyro-ui/fonts/geist-mono.css, иначе текст будет системным шрифтом; glass использует системные шрифты, ей файлы не нужны. Пока пакет не опубликован, соберите и упакуйте его в репозитории (npm run build:core && npm pack ./dist/core) и установите tarball из корня репозитория: npm install /path/to/ValyroUI/valyro-ui-0.1.0.tgz.

npm install valyro-ui

3. Стили и тема в корневом маршруте

Импорт с ?url превращает CSS в <link> в <head> серверного HTML — так подключён и CSS самого шаблона, и порядок явный: сначала ValyroUI, потом ваши стили. Обычный import 'valyro-ui/styles.css' тоже даёт ссылку в <head>, но после ссылок из links, и тогда стили ValyroUI перебивают ваши. Атрибуты темы — на <html>, ThemeProvider с теми же значениями — вокруг children. При SSR задайте locale в ThemeProvider: иначе числа и даты форматируются по локали сервера, а в браузере — по локали пользователя, и гидрация падает на несовпадении текста («1,200» против «1 200»).

import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'
import { ThemeProvider } from 'valyro-ui'
import valyroCss from 'valyro-ui/styles.css?url'

import appCss from '../styles.css?url'

export const Route = createRootRoute({
  head: () => ({
    meta: [
      { charSet: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { title: 'ValyroUI on TanStack Start' },
    ],
    links: [
      { rel: 'stylesheet', href: valyroCss },
      { rel: 'stylesheet', href: appCss },
    ],
  }),
  shellComponent: RootDocument,
})

function RootDocument({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" data-theme="glass" data-mode="light">
      <head>
        <HeadContent />
      </head>
      <body>
        <ThemeProvider theme="glass" mode="light" locale="en-US">
          {children}
        </ThemeProvider>
        <Scripts />
      </body>
    </html>
  )
}

4. Уберите шрифт и вёрстку шаблона

Шаблонный font-family на body перебивает шрифт темы, а правило для main меняет вёрстку страниц. Оставьте только сброс.

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

5. Маршрут

Showcase — компонент из гайда по Next.js, без изменений (директиву 'use client' TanStack Start пропускает молча).

import { createFileRoute } from '@tanstack/react-router'

import { Showcase } from '../Showcase'

export const Route = createFileRoute('/')({ component: Home })

function Home() {
  return <Showcase />
}

6. Соберите и запустите

npm run preview отдаёт SSR из production-сборки. Для деплоя на Node нужен адаптер хостинга из документации TanStack Start.

npx tsc --noEmit
npm run build
npm run preview

Другие фреймворки