Next.js
How to install and set up OUI in a Next.js project
This guide will help you set up OUI in a new or existing Next.js project with Tailwind CSS v4.
OUI has been tested with the following dependency versions:
- Next.js 14 or later
- React 18 or later
- Tailwind CSS v4
- Motion 12 or later
Create a new Next.js project
If you're starting from scratch, create a new Next.js project (or use Starter Kit):
npx create-next-app@latest my-app --typescript --eslint
cd my-appInstallation (with App Router)
Install dependencies
Install OUI packages and peer dependencies:
npm install @opengovsg/oui @opengovsg/oui-theme react-aria-components motionInstall Tailwind CSS v4
Install Tailwind CSS v4 and the PostCSS plugin:
npm install tailwindcss @tailwindcss/postcssConfigure PostCSS
Create or update your postcss.config.mjs file to use the Tailwind CSS plugin:
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
}
export default configSet up your CSS file
Create or update your global CSS file (e.g., app/globals.css) to import the OUI theme:
@import "@opengovsg/oui-theme/tailwind.css";
/*
* Note: You may need to change the path relative to this css file to fit your
* project structure, especially in a monorepo.
*/
@source "../path/to/node_modules/@opengovsg/oui-theme";This import includes:
- Tailwind CSS v4 base styles
- OUI design tokens and theme variables
- React Aria Components integration via
tailwindcss-react-aria-components - Animation utilities via
tw-animate-css
Set up Inter font
There are a few ways to set up the Inter font in your Next.js project:
Using next/font
One way is to use the next/font package:
import { Inter } from "next/font/google"
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
})Then, add the font variable to your HTML or body element:
<html lang="en" className={inter.variable}>
<body>{children}</body>
</html>You will also need to ensure that your Tailwind configuration uses the Inter font for the --font-sans CSS variable:
@import "@opengovsg/oui-theme/tailwind.css";
@source "../path/to/node_modules/@opengovsg/oui-theme";
@theme {
--font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}Using the Inter NPM package
Alternatively, you can use the inter-ui NPM package.
Install the package:
npm install inter-uiThen, import the font CSS in your global CSS file:
@import "@opengovsg/oui-theme/tailwind.css";
@source "../path/to/node_modules/@opengovsg/oui-theme";
@import "inter-ui/inter.css";
@import "inter-ui/inter-variable.css";
@layer base {
:root {
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
@supports (font-variation-settings: normal) {
--font-sans: "InterVariable", ui-sans-serif, system-ui, sans-serif;
}
}
}Import CSS in your layout
Make sure your CSS file is imported in your root layout:
import type { Metadata } from "next"
import "./globals.css"
export const metadata: Metadata = {
title: "My App",
description: "My app description",
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}Set up react-aria-components Link provider
To enable client-side navigation when using OUI's Link component with Next.js's router,
wrap your app with the RouterProvider from react-aria-components:
"use client"
import { useRouter } from "next/navigation"
import { RouterProvider } from "react-aria-components"
export function Providers({ children }: { children: React.ReactNode }) {
const router = useRouter()
return <RouterProvider navigate={router.push}>{children}</RouterProvider>
}Then use it in your layout:
import type { Metadata } from "next"
import { Providers } from "./providers"
import "./globals.css"
export const metadata: Metadata = {
title: "My App",
description: "My app description",
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
)
}Read more about setting up client-side routing with react-aria-components in the React Aria frameworks guide.
Start using OUI components
You're all set! Start using OUI components in your app.
Note: Next.js's
app/directory uses Server Components by default. OUI components can be imported directly in Server Components since components have theuse clientdirective added.However, if errors occur, add the
"use client"directive at the top of files that use OUI components, or wrap them in a Client Component.
"use client"
import { Button } from "@opengovsg/oui"
export default function Home() {
return (
<div className="flex min-h-screen items-center justify-center gap-4">
<Button>Default</Button>
<Button color="main">Main</Button>
<Button variant="outline">Outline</Button>
</div>
)
}App Router vs Pages Router
The examples above use the App Router (Next.js 13+). If you're using the Pages Router, the setup is similar:
- Import your CSS in
pages/_app.tsxinstead ofapp/layout.tsx - Wrap your app with providers in
pages/_app.tsx
import type { AppProps } from "next/app"
import { useRouter } from "next/router"
import { RouterProvider } from "react-aria-components"
import "../styles/globals.css"
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter()
return (
<RouterProvider navigate={router.push}>
<Component {...pageProps} />
</RouterProvider>
)
}TypeScript configuration
For the best TypeScript experience, ensure your tsconfig.json includes:
{
"compilerOptions": {
"moduleResolution": "bundler",
"jsx": "preserve"
}
}Next steps
- Browse the Components documentation to explore available components
- Check out the Theming guide to customize the design system