next-intl provides two ways to format dates: using the useFormatter hook for dates outside messages, and embedding ICU syntax directly in translation strings for dates that are part of a message.
next-intl provides comprehensive date formatting that automatically adapts to the user's locale. You have two primary approaches depending on your use case: formatting standalone dates (like timestamps or labels) using the useFormatter hook, or embedding dates within translated messages using ICU syntax. The library is built on the native Intl.DateTimeFormat API and supports all standard options, ensuring consistent formatting across both client and server components.
For dates that are not part of a larger translated message (e.g., a timestamp in a UI widget), use the useFormatter hook. This hook returns a format object containing a dateTime method. The method accepts a Date object and formatting options that follow the standard Intl.DateTimeFormat API.
For dates that appear inside a larger sentence or phrase (e.g., "Ordered on {date}"), you should embed the date formatting directly in your translation message. This keeps all text for a sentence together, which is much easier for translators. Use the ICU syntax with the date keyword.
full: Full date format, e.g., "Tuesday, November 20, 2020"
long: Long date format, e.g., "November 20, 2020"
medium: Medium date format, e.g., "Nov 20, 2020"
short: Short date format, e.g., "11/20/20"
::yyyyMMMd: Custom date skeleton for precise control, e.g., "Jul 9, 2024"
next-intl also provides relativeTime for formatting dates relative to the current moment (e.g., "2 hours ago", "in 3 days"). This is available through the same useFormatter hook.
When formatting dates in Server Components, note that getFormatter is an asynchronous function and must be awaited. Forgetting await will result in a "is not a function" error.
Use ISO 8601 strings (e.g., '2020-11-20T10:36:01.516Z') for date storage to ensure consistent parsing across time zones
For dates inside messages, use ICU syntax so translators can adjust format according to locale conventions
For UI elements where the date appears alone, use useFormatter for more flexibility
Use useNow with updateInterval for relative times that need to refresh automatically
In Server Components, always await getFormatter before using it
For complex date manipulations (e.g., adding days, parsing), use libraries like date-fns alongside next-intl