HQ UI

Vite

Learn how to integrate HQ UI in Vite React Project

Create New Project

Run the init command to create a new Next.js project or to setup an existing one:

npx shadcn@latest init https://hq-ui.vercel.app/r/default

Registry

First, add the HQ UI in your components.json:

components.json
  ...
  "registries": {
    "@hq": "https://hq-ui.vercel.app/r/{name}"
  }

Add Components

You can now start adding components to your project.

npx shadcn@latest add @hq/button

Or if you don't wan't to modify components.json, you can use this command

npx shadcn@latest add https://hq-ui.vercel.app/r/button

Client Side Routing

Vite does not support client side routing out of the box, but you can use react-router-dom or simply use Framework such as nextjs, react-router, or tanstack

React Router Dom

If you want to use react-router-dom, first install the package.

npm i react-router-dom

Client Provider

First create a src/components/client-provider.tsx file

client-provider.tsx
import type { PropsWithChildren } from "react";
import { RouterProvider } from "react-aria-components";
import { useNavigate } from "react-router-dom";

export function ClientProvider({ children }: PropsWithChildren) {
  const navigate = useNavigate();
  return (
    <RouterProvider navigate={(to, options) => navigate(to, options)}>
      {children}
    </RouterProvider>
  );
}

Modify your App.tsx file or create new file such as router.tsx

router.tsx
import { BrowserRouter, Routes, Route } from "react-router-dom"
import { Link } from "react-aria-components"
import Home from "./pages/home"
import About from "./pages/about"
import { ClientProvider } from "./components/client-provider"

export default function App() {
  return (
    <BrowserRouter>
      <ClientProvider>
        <nav>
          <Link href="/">Home</Link>
          <Link href="/about">About</Link>
        </nav>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </ClientProvider>
    </BrowserRouter>
  )
}

Use it in your root main.tsx file.

main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./router.tsx";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

Dark Mode

Theme Provider

If you are using the New Shadcn CLI, Theme Provider is already added. You can skip this step

Theme Switcher

npm i @tabler/icons-react
components/theme-switcher.tsx
import { useTheme } from './theme-provider'
import { IconMoon, IconSun } from '@tabler/icons-react'
import { Button } from './ui/button'

export function ThemeSwitcher({ variant = 'outline' }: { variant?: 'outline' | 'ghost' }) {
  const { resolvedTheme, setTheme } = useTheme()

  return (
    <Button
      aria-label={`Switch to ${resolvedTheme}` === 'light' ? 'dark' : 'light' + 'mode'}
      onPress={() => setTheme(resolvedTheme === 'light' ? 'dark' : 'light')}
      size='icon'
      variant={variant}
    >
      <IconSun aria-hidden className='rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0' />
      <IconMoon aria-hidden className='absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100' />
    </Button>
  )
}