Skip to content

Next.js

Terminal window
bun add typewritingclass typewritingclass-react typewritingclass-next

Add <TWCStyles /> in <head> for SSR styles, and a client-side <TWCInject /> for runtime injection during development:

app/layout.tsx
import { TWCStyles } from 'typewritingclass-next'
import { TWCInject } from './twc-inject'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<TWCStyles />
</head>
<body>
<TWCInject />
{children}
</body>
</html>
)
}
app/twc-inject.tsx
'use client'
import 'typewritingclass/inject'
export function TWCInject() {
return null
}

TWCStyles is a Server Component that renders a <style data-twc> tag with all registered CSS. TWCInject loads the runtime injector on the client so styles added after SSR are picked up.

Use tw directly — no hooks, no client boundary:

import { tw } from 'typewritingclass'
export default function Home() {
return (
<div className={`${tw.flex.flexCol.gap(8).p(8).items('center')}`}>
<h1 className={`${tw.text('2xl').font('700').textColor('slate-900')}`}>
Hello from Next.js
</h1>
<div className={`${tw.p(6).bg('white').rounded('lg').shadow('md').hover.shadow('lg')}`}>
Hover this card
</div>
</div>
)
}

For static styles, tw works the same with 'use client'. For dynamic values, use useStyle():

'use client'
import { useStyle } from 'typewritingclass-react'
import { p, bg, rounded, dynamic } from 'typewritingclass'
export function Banner({ color }: { color: string }) {
const props = useStyle(p(6), bg(dynamic(color)), rounded('lg'))
return <div {...props}>Welcome!</div>
}

For production, wrap your Next config with withTwc to extract CSS at build time via the Babel plugin:

next.config.mjs
import { withTwc } from 'typewritingclass-next/plugin'
export default withTwc({
// your Next.js config
})

Options:

OptionTypeDefaultDescription
outputFilestring".next/twc.css"Path for extracted CSS
strictbooleanfalseError on non-static cx() args
export default withTwc({}, { strict: true })