Skip to content

Next.js

Terminal window
npm install date-wiz

date-wiz works in all Next.js rendering modes: Server Components, Client Components, API Routes, and Edge Runtime.


Because date-wiz has zero dependencies and uses native APIs, it runs perfectly in React Server Components:

app/posts/[id]/page.tsx
import { format, smartFormat } from 'date-wiz';
async function PostPage({ params }: { params: { id: string } }) {
const post = await getPost(params.id);
return (
<article>
<h1>{post.title}</h1>
<time dateTime={post.publishedAt.toISOString()}>
{smartFormat(post.publishedAt)}
</time>
<p>Published: {format(post.publishedAt, 'DD MMMM YYYY')}</p>
</article>
);
}

'use client';
import { useEffect, useState } from 'react';
import { getRelativeTime } from 'date-wiz';
export function LiveRelativeTime({
date,
locale = 'en',
}: {
date: Date;
locale?: string;
}) {
const [label, setLabel] = useState('');
useEffect(() => {
// Set immediately on mount (avoids SSR mismatch)
setLabel(getRelativeTime(date, { locale }));
const id = setInterval(() => {
setLabel(getRelativeTime(date, { locale }));
}, 30_000);
return () => clearInterval(id);
}, [date, locale]);
return (
<time suppressHydrationWarning dateTime={date.toISOString()}>
{label}
</time>
);
}

app/api/events/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { format, getRelativeTime } from 'date-wiz';
export async function GET(req: NextRequest) {
const locale = req.headers.get('accept-language')?.split(',')[0] ?? 'en';
const events = await getUpcomingEvents();
return NextResponse.json(
events.map(e => ({
...e,
startsAt: format(e.startsAt, 'LLL', locale),
startsIn: getRelativeTime(e.startsAt, { locale }),
})),
);
}

middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(req: NextRequest) {
const response = NextResponse.next();
// Forward the user's locale to downstream RSCs via a header
const locale = req.headers.get('accept-language')?.split(',')[0] ?? 'en';
response.headers.set('x-user-locale', locale);
return response;
}

Then read it in a Server Component:

import { headers } from 'next/headers';
import { format } from 'date-wiz';
async function EventCard({ event }: { event: Event }) {
const locale = (await headers()).get('x-user-locale') ?? 'en';
return <p>{format(event.date, 'LLL', locale)}</p>;
}