TanStack Router

A guide for installing and using Yamada UI with TanStack Router projects.

Installation

  • 1

    Create application

    Create TanStack Router application.

    pnpm dlx create-tsrouter-app my-app
    
  • 2

    Setup

    Running the command will create the necessary files and folders in your project.

    pnpm dlx @yamada-ui/cli init
    
  • 3

    Install the package

    Install @workspaces/ui to your application.

    pnpm add "@workspaces/ui@workspace:*"
    
  • 4

    Add provider

    After installing, add UIProvider to the root of your application.

    main.tsx

    import ReactDOM from "react-dom/client"
    import { RouterProvider, createRouter } from "@tanstack/react-router"
    import { routeTree } from "./routeTree.gen"
    import { UIProvider } from "@workspaces/ui"
    
    const router = createRouter({
      routeTree,
      defaultPreload: "intent",
      scrollRestoration: true,
    })
    
    declare module "@tanstack/react-router" {
      interface Register {
        router: typeof router
      }
    }
    
    const rootElement = document.getElementById("app")!
    
    if (!rootElement.innerHTML) {
      const root = ReactDOM.createRoot(rootElement)
      root.render(
        <UIProvider>
          <RouterProvider router={router} />
        </UIProvider>,
      )
    }
    
  • 5

    Use components

    After adding UIProvider, you can use the components in your application.

    index.tsx

    import { createFileRoute } from "@tanstack/react-router"
    import { Button } from "@workspaces/ui"
    
    export const Route = createFileRoute("/")({ component: App })
    
    function App() {
      return <Button>Click me!</Button>
    }
    

    That's it! You've successfully set up Yamada UI.

Scripts

ColorModeScript

To use Color Mode, you need to add ColorModeScript to the body to ensure it works correctly.

This is because color mode is implemented using localStorage or cookies, and adding the script ensures proper synchronization when the page loads.

vite.config.ts

import viteReact from "@vitejs/plugin-react"
import type { Plugin } from "vite"
import { defineConfig } from "vite"
import tsconfigPaths from "vite-tsconfig-paths"
import { devtools } from "@tanstack/devtools-vite"
import { tanstackRouter } from "@tanstack/router-plugin/vite"
import { COLOR_MODE_STORAGE_KEY, getStorageScript } from "@workspaces/ui"

function injectColorModeScript(): Plugin {
  return {
    name: "inject-color-mode-script",
    transformIndexHtml(html) {
      const content = getStorageScript(
        "colorMode",
        COLOR_MODE_STORAGE_KEY,
      )({ defaultValue: "light" })

      return html.replace("<body>", `<body><script>${content}</script>`)
    },
  }
}

const config = defineConfig({
  plugins: [
    devtools(),
    tsconfigPaths({ projects: ["./tsconfig.json"] }),
    tanstackRouter({ target: "react", autoCodeSplitting: true }),
    viteReact(),
    injectColorModeScript(),
  ],
})

export default config

If you change the defaultColorMode in your config, set the defaultValue prop on ColorModeScript.

vite.config.ts

import viteReact from "@vitejs/plugin-react"
import type { Plugin } from "vite"
import { defineConfig } from "vite"
import tsconfigPaths from "vite-tsconfig-paths"
import { devtools } from "@tanstack/devtools-vite"
import { tanstackRouter } from "@tanstack/router-plugin/vite"
import { COLOR_MODE_STORAGE_KEY, getStorageScript } from "@workspaces/ui"
import { config as themeConfig } from "@workspaces/theme"

function injectColorModeScript(): Plugin {
  return {
    name: "inject-color-mode-script",
    transformIndexHtml(html) {
      const content = getStorageScript(
        "colorMode",
        COLOR_MODE_STORAGE_KEY,
      )({ defaultValue: themeConfig.defaultColorMode })

      return html.replace("<body>", `<body><script>${content}</script>`)
    },
  }
}

const config = defineConfig({
  plugins: [
    devtools(),
    tsconfigPaths({ projects: ["./tsconfig.json"] }),
    tanstackRouter({ target: "react", autoCodeSplitting: true }),
    viteReact(),
    injectColorModeScript(),
  ],
})

export default config

ThemeSchemeScript

To use theme switching, you need to add ThemeSchemeScript to the body to ensure it works correctly.

This is because theme switching is implemented using localStorage or cookies, and adding the script ensures proper synchronization when the page loads.

vite.config.ts

import viteReact from "@vitejs/plugin-react"
import type { Plugin } from "vite"
import { defineConfig } from "vite"
import tsconfigPaths from "vite-tsconfig-paths"
import { devtools } from "@tanstack/devtools-vite"
import { tanstackRouter } from "@tanstack/router-plugin/vite"
import { THEME_SCHEME_STORAGE_KEY, getStorageScript } from "@workspaces/ui"

function injectThemeSchemeScript(): Plugin {
  return {
    name: "inject-theme-scheme-script",
    transformIndexHtml(html) {
      const content = getStorageScript(
        "themeScheme",
        THEME_SCHEME_STORAGE_KEY,
      )({ defaultValue: "base" })

      return html.replace("<body>", `<body><script>${content}</script>`)
    },
  }
}

const config = defineConfig({
  plugins: [
    devtools(),
    tsconfigPaths({ projects: ["./tsconfig.json"] }),
    tanstackRouter({ target: "react", autoCodeSplitting: true }),
    viteReact(),
    injectThemeSchemeScript(),
  ],
})

export default config

If you change the defaultThemeScheme in your config, set the defaultValue prop on ThemeSchemeScript.

vite.config.ts

import viteReact from "@vitejs/plugin-react"
import type { Plugin } from "vite"
import { defineConfig } from "vite"
import tsconfigPaths from "vite-tsconfig-paths"
import { devtools } from "@tanstack/devtools-vite"
import { tanstackRouter } from "@tanstack/router-plugin/vite"
import { THEME_SCHEME_STORAGE_KEY, getStorageScript } from "@workspaces/ui"
import { config as themeConfig } from "@workspaces/theme"

function injectThemeSchemeScript(): Plugin {
  return {
    name: "inject-theme-scheme-script",
    transformIndexHtml(html) {
      const content = getStorageScript(
        "themeScheme",
        THEME_SCHEME_STORAGE_KEY,
      )({ defaultValue: themeConfig.defaultThemeScheme })

      return html.replace("<body>", `<body><script>${content}</script>`)
    },
  }
}

const config = defineConfig({
  plugins: [
    devtools(),
    tsconfigPaths({ projects: ["./tsconfig.json"] }),
    tanstackRouter({ target: "react", autoCodeSplitting: true }),
    viteReact(),
    injectThemeSchemeScript(),
  ],
})

export default config

Component Integration

You can integrate TanStack Router components such as Link with Yamada UI components.

import type { LinkComponent } from "@tanstack/react-router"
import { createLink } from "@tanstack/react-router"
import { Button, IconButton, Link } from "@workspaces/ui"

const CreatedLink = createLink(Link)

export const RouterLink: LinkComponent<typeof CreatedLink> = (props) => {
  return <CreatedLink {...props} />
}

const CreatedLinkButton = createLink(Button)

export const RouterLinkButton: LinkComponent<typeof CreatedLinkButton> = (
  props,
) => {
  return <CreatedLinkButton {...props} />
}

const CreatedLinkIconButton = createLink(IconButton)

export const RouterLinkIconButton: LinkComponent<
  typeof CreatedLinkIconButton
> = (props) => {
  return <CreatedLinkIconButton {...props} />
}