How to format dates for different locales in Next.js (Pages Router) v16

Display dates in region-specific formats

Problem

Dates do not have a universal written format. The sequence 10/12/2025 means October 12 in the United States but December 10 in the United Kingdom. Writing "Oct 12, 2025" assumes English month names and a particular ordering convention. Every region has its own expectations about date format, including the order of components, separators, and whether month names appear as words or numbers.

Displaying dates in a single format makes the application feel foreign to users outside that format's region. Users may misinterpret dates or find them harder to read. A date that is clear to one audience can be confusing or ambiguous to another.

Solution

Format dates based on the user's locale, turning date values into strings that follow regional rules for order, separators, and month names. The browser's Intl.DateTimeFormat API handles the locale-specific formatting rules automatically when given a locale and optional formatting preferences.

react-intl provides components and hooks that wrap this API and integrate with the application's locale context. By passing date values and formatting options to these tools, dates render in a way that is both clear and natural for the user's language and region.

Steps

1. Create a date formatting component using FormattedDate

The FormattedDate component accepts a date value and formatting options that conform to Intl.DateTimeFormatOptions. Create a component that displays a date with the desired level of detail.

import { FormattedDate } from "react-intl";

interface EventDateProps {
  date: Date;
}

export function EventDate({ date }: EventDateProps) {
  return (
    <time dateTime={date.toISOString()}>
      <FormattedDate value={date} year="numeric" month="long" day="numeric" />
    </time>
  );
}

FormattedDate reads the locale from the IntlProvider context and formats the date accordingly. The component will display "October 12, 2025" for en-US and "12 October 2025" for en-GB.

2. Format dates imperatively with useIntl

For cases where a React component cannot be used, such as setting text attributes, use the useIntl hook to access the formatDate method.

import { useIntl } from "react-intl";

interface ArticleImageProps {
  src: string;
  publishedAt: Date;
}

export function ArticleImage({ src, publishedAt }: ArticleImageProps) {
  const intl = useIntl();

  const formattedDate = intl.formatDate(publishedAt, {
    year: "numeric",
    month: "short",
    day: "numeric",
  });

  return <img src={src} alt={`Article published on ${formattedDate}`} />;
}

The formatDate method returns a formatted date string and accepts options that conform to DateTimeFormatOptions. This approach is useful for attributes, server-side code, or performance-critical scenarios.

3. Adjust formatting detail with standard options

Control the presentation of date components by specifying options like year, month, day, and weekday with values such as "numeric", "2-digit", "long", "short", or "narrow".

import { FormattedDate } from "react-intl";

export function FullEventDate({ date }: { date: Date }) {
  return (
    <FormattedDate
      value={date}
      weekday="long"
      year="numeric"
      month="long"
      day="numeric"
    />
  );
}

export function CompactDate({ date }: { date: Date }) {
  return (
    <FormattedDate value={date} year="2-digit" month="2-digit" day="2-digit" />
  );
}

The FullEventDate component will render "Monday, October 12, 2025" in en-US and "Montag, 12. Oktober 2025" in de-DE. The CompactDate component produces shorter numeric formats appropriate for tables or tight layouts.

4. Create a reusable date formatter helper

For consistent date formatting across multiple pages, create a helper function that encapsulates common formatting patterns.

import { useIntl } from "react-intl";

export function useDateFormatters() {
  const intl = useIntl();

  return {
    formatShortDate: (date: Date) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "short",
        day: "numeric",
      }),

    formatLongDate: (date: Date) =>
      intl.formatDate(date, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
      }),

    formatMonthYear: (date: Date) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "long",
      }),
  };
}

Import and use this hook in any page component to format dates consistently without repeating options.

5. Use the helper in a page component

Apply the date formatter helper in a Next.js page to display locale-aware dates.

import { GetStaticProps } from "next";
import { useDateFormatters } from "../lib/useDateFormatters";

interface Post {
  title: string;
  publishedAt: string;
  content: string;
}

interface BlogPostPageProps {
  post: Post;
}

export default function BlogPostPage({ post }: BlogPostPageProps) {
  const { formatLongDate } = useDateFormatters();
  const publishedDate = new Date(post.publishedAt);

  return (
    <article>
      <h1>{post.title}</h1>
      <p>Published: {formatLongDate(publishedDate)}</p>
      <div>{post.content}</div>
    </article>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const post = {
    title: "Understanding Internationalization",
    publishedAt: "2025-10-12T00:00:00Z",
    content: "Content here...",
  };

  return {
    props: { post },
  };
};

The page will display the publication date in the user's locale format, making the date immediately clear and familiar to readers in any region.