Next.js
This library requires React 19+
There are four steps to installation:
- Install the npm packages
- Import the CSS
- Configure fonts
- Configure theme provider
This guide assumes you're using Next.js with the app router.
1. Install the npm packages
pnpm add @qualcomm-ui/react @qualcomm-ui/react-core @qualcomm-ui/core @qualcomm-ui/qds-core @qualcomm-ui/dom @qualcomm-ui/utils @tanstack/react-virtual lucide-react
npm i @qualcomm-ui/react @qualcomm-ui/react-core @qualcomm-ui/core @qualcomm-ui/qds-core @qualcomm-ui/dom @qualcomm-ui/utils @tanstack/react-virtual lucide-react
yarn add @qualcomm-ui/react @qualcomm-ui/react-core @qualcomm-ui/core @qualcomm-ui/qds-core @qualcomm-ui/dom @qualcomm-ui/utils @tanstack/react-virtual lucide-react
2. Import the CSS
In your app/globals.css file, import the QUI styles.
@import "@qualcomm-ui/qds-core/styles/components.css";
@import "@qualcomm-ui/qds-core/themes/qualcomm-dark.css";
@import "@qualcomm-ui/qds-core/themes/qualcomm-light.css";
:root {
--type-font-family-secondary: var(--font-roboto-flex), sans-serif;
--type-font-family-tertiary: var(--font-roboto-mono), monospace;
}@import "tailwindcss";
/* Recommended: install and import @qualcomm-ui/tailwind-plugin */
@import "@qualcomm-ui/tailwind-plugin/qui-strict.css";
/* Important: always order these imports after the tailwindcss import */
@import "@qualcomm-ui/qds-core/styles/components.css" layer(components);
@import "@qualcomm-ui/qds-core/themes/qualcomm-light.css" layer(components);
@import "@qualcomm-ui/qds-core/themes/qualcomm-dark.css" layer(components);
:root {
--type-font-family-secondary: var(--font-roboto-flex);
--type-font-family-tertiary: var(--font-roboto-mono);
}Learn more about the available brands in the theme documentation.
3. Configure fonts
QUI components are designed with the Roboto Flex and Roboto Mono font families.
In Next.js, configure fonts using next/font/google and set up the theme provider in your root layout:
import type {Metadata} from "next"
import {Roboto_Flex, Roboto_Mono} from "next/font/google"
import "./globals.css"
import {type ReactNode} from "react"
const sansFont = Roboto_Flex({
variable: "--font-roboto-flex",
weight: ["400", "500", "600"],
subsets: ["latin"],
})
const monoFont = Roboto_Mono({
variable: "--font-roboto-mono",
subsets: ["latin"],
})
export const metadata: Metadata = {
title: "Your App Title",
description: "Your app description",
}
export default function RootLayout({
children,
}: Readonly<{
children: ReactNode
}>) {
return (
<html lang="en">
<body className={`${sansFont.variable} ${monoFont.variable}`}>
{children}
</body>
</html>
)
}4. Configure the theme provider
QUI styles support both light and dark modes. This step configures theme storage using cookies so the user's preferred theme is remembered and rendered without flash on page load.
Create the ThemeProvider
First, create a ThemeProvider component at app/components/theme-provider.tsx:
"use client"
import {
createContext,
type ReactNode,
useCallback,
useContext,
useState,
} from "react"
import type {QdsTheme} from "@qualcomm-ui/qds-core/theme"
type ThemeContextValue = {
setTheme: (theme: QdsTheme) => void
theme: QdsTheme
toggleTheme: () => void
}
const ThemeContext = createContext<ThemeContextValue | null>(null)
export function useTheme(): ThemeContextValue {
const context = useContext(ThemeContext)
if (!context) {
throw new Error("useTheme must be used within a ThemeProvider")
}
return context
}
type ThemeProviderProps = {
children: ReactNode
defaultTheme: QdsTheme
}
export function ThemeProvider({
children,
defaultTheme,
}: ThemeProviderProps): ReactNode {
const [theme, setThemeState] = useState<QdsTheme>(defaultTheme)
const setTheme = useCallback((newTheme: QdsTheme) => {
document.cookie = `app-qds-theme=${newTheme}; path=/; max-age=31536000`
document.documentElement.setAttribute("data-theme", newTheme)
setThemeState(newTheme)
}, [])
const toggleTheme = useCallback(() => {
setTheme(theme === "dark" ? "light" : "dark")
}, [theme, setTheme])
return (
<ThemeContext.Provider value={{setTheme, theme, toggleTheme}}>
{children}
</ThemeContext.Provider>
)
}Update the root layout
Update your app/layout.tsx to read the theme cookie server-side and pass it to the provider:
// previous imports and setup...
import {cookies} from "next/headers"
import type {QdsTheme} from "@qualcomm-ui/qds-core/theme"
import {ThemeProvider} from "./components/theme-provider"
export default async function RootLayout({
children,
}: Readonly<{
children: ReactNode
}>) {
const cookieStore = await cookies()
const themeCookie = cookieStore.get("theme")
const theme: QdsTheme = themeCookie?.value === "light" ? "light" : "dark"
return (
<html
lang="en"
data-brand="qualcomm"
data-theme={theme}
style={{colorScheme: theme}}
>
<body className={`${sansFont.variable} ${monoFont.variable}`}>
<ThemeProvider defaultTheme={theme}>{children}</ThemeProvider>
</body>
</html>
)
}Key configuration details:
cookies()reads the theme preference server-side to prevent flash of wrong themedata-theme={theme}on<html>ensures correct theme on first renderdata-brand="qualcomm"sets the brand (change to"snapdragon"or"dragonwing"for other brands)
import "./globals.css"
import type {ReactNode} from "react"
import type {Metadata} from "next"
import {Roboto_Flex, Roboto_Mono} from "next/font/google"
import {cookies} from "next/headers"
import type {QdsTheme} from "@qualcomm-ui/qds-core/theme"
import {ThemeProvider} from "./components/theme-provider"
const sansFont = Roboto_Flex({
subsets: ["latin"],
variable: "--font-roboto-flex",
weight: ["400", "500", "600"],
})
const monoFont = Roboto_Mono({
subsets: ["latin"],
variable: "--font-roboto-mono",
})
export const metadata: Metadata = {
description: "Your app description",
title: "Your App Title",
}
export default async function RootLayout({
children,
}: Readonly<{
children: ReactNode
}>) {
const cookieStore = await cookies()
const themeCookie = cookieStore.get("app-qds-theme")
const theme: QdsTheme = themeCookie?.value === "light" ? "light" : "dark"
return (
<html lang="en" data-brand="qualcomm" data-theme={theme}>
<body className={`${sansFont.variable} ${monoFont.variable} antialiased`}>
<ThemeProvider defaultTheme={theme}>{children}</ThemeProvider>
</body>
</html>
)
}Your application is now ready to import and use our components. An example application with this configuration is available in our templates repository.
Next Steps
- Learn more about theming in our theming documentation.
- Use the navigation menu on the left to view component documentation and examples.
Using the theme
Import the useTheme hook from your theme provider to access and toggle the theme:
import {useTheme} from "./components/theme-provider"
function ThemeToggle() {
const {theme, toggleTheme} = useTheme()
return <button onClick={toggleTheme}>Current theme: {theme}</button>
}Customize the default theme
The default theme is "dark" when no cookie is set. To change this, modify the fallback in your layout:
const theme: QdsTheme = themeCookie?.value === "dark" ? "dark" : "light"To set a different brand, change the data-brand attribute on the <html> element:
<html lang="en" data-brand="snapdragon" data-theme={theme} style={{colorScheme: theme}}>Troubleshooting
Styles aren't loading
If @qualcomm-ui/react components are appearing without styles, check the following:
- Ensure that you've imported the CSS from step 2.
- Verify that you've configured the theme provider from step 4.
If styles still aren't appearing, inspect the DOM of your application in your browser's dev tools. Your application's <html> element should have at least two attributes:
data-brand: the QDS brand (eitherqualcomm,snapdragon, ordragonwing)data-theme: the QDS theme (eitherlightordark)
Your <html> element should look something like this:
<html
data-brand="qualcomm"
data-theme="light"
style="color-scheme: light"
></html>Note that you need to import the corresponding CSS for the brand you've selected:
@import "@qualcomm-ui/qds-core/themes/qualcomm-dark.css";
@import "@qualcomm-ui/qds-core/themes/qualcomm-light.css";@import "@qualcomm-ui/qds-core/themes/snapdragon-dark.css";
@import "@qualcomm-ui/qds-core/themes/snapdragon-light.css";@import "@qualcomm-ui/qds-core/themes/dragonwing-dark.css";
@import "@qualcomm-ui/qds-core/themes/dragonwing-light.css";Component Styles
Always import component styles, regardless of the chosen brand.
@import "@qualcomm-ui/qds-core/styles/components.css";Migrating from legacy QUI
NextGen is independent of the legacy @qui/react package. Both can be installed and used in the same project without conflicts.
/* this is fine */
@import "@qui/styles/dist/all.min.css";
@import "@qui/base/dist/all.min.css";
@import "@qualcomm-ui/qds-core/styles/components.css";
@import "@qualcomm-ui/qds-core/themes/qualcomm-dark.css";
@import "@qualcomm-ui/qds-core/themes/qualcomm-light.css";NOTE
We're working on a codemod script to automate the migration process. Check back regularly for updates!