shadcn.io is not affiliated with official shadcn/ui
Relative Time Text says a moment the way people do: now, then 12 seconds ago, 5 minutes ago, yesterday, last month; and ahead, in 3 days or next year. It keeps itself true as time passes, and each change fades in. Hovering shows the full date and time.
Use it for a chat message, a "last updated" line, an activity feed, a comment, or a renewal date. For the time of day, use Clock Text; for a live countdown to a moment, Countdown Text. The words come from Intl.RelativeTimeFormat, in any locale, and a small timer wakes only when they would change: every second in the first minute, then each minute, then each hour. The fade is a CSS transition, with no animation library.
Installation
Usage
import { RelativeTimeText } from "@/components/ui/relative-time-text";<RelativeTimeText timestamp={comment.createdAt} />Demos
Live
A moment that just happened reads now, then counts the seconds, then the minutes. Here, each save sets timestamp to that moment.
Future
A moment still to come reads in 8 months, next week or tomorrow, and turns into the past once it's gone. timestamp can be a Date, a timestamp in milliseconds, or a date string.
Format
format is how long the words are: long, the default, short or narrow. numeric="always" says 1 day ago rather than yesterday. The words are in locale, en-US by default.
Accessibility
It renders a <time> element whose dateTime is the moment itself, so the words and the exact date travel together, and its title gives the full date and time. Screen readers read the words as they are when reached; changes aren't announced, which is right for a timestamp. The text keeps its own direction on a right-to-left page. With reduced motion new words fade in without moving.
FAQ
Why does it show a date first?
How long ago something was depends on the visitor's clock, which the server can't know. So the server renders the date itself, in UTC, which reads the same everywhere and is what a page without JavaScript shows; the words replace it as soon as the page runs, and the server and the browser render the same markup.
How often does it update?
Only when the words would change: each second for the first minute, then at each new minute, then each hour, and at most once a day after that. Between changes it does nothing.
Which unit does it pick?
The largest that fits: seconds under a minute, then minutes, hours, days, weeks after seven days, months after thirty, and years after 365. The count is whole units, rounded down, so 1 hour 50 minutes ago reads 1 hour ago.
What about moments in the future?
They read in 5 minutes, tomorrow, next month, and change to the past once they've gone by.
API Reference
RelativeTimeText
<time> data-slot="relative-time-text"
timestampDate | number | string
The moment it describes, past or future: a Date, a timestamp in
milliseconds or a date string.
- Type
Date | number | string
format?Length
How long the words are: 5 minutes ago, 5 min. ago or 5m ago. @default "long".
- Default
"long"
locale?string
The locale it's written in. Fixed by default, so the server and the browser write the date it shows first the same way.
- Default
"en-US"
numeric?"auto" | "always"
Whether it says yesterday, now and next week, or always a number
(1 day ago).
- Type
"auto" | "always"- Default
"auto"
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
Related
- Pro
Clock Text
NumbersThe time of day, live
- Pro
Countdown Text
NumbersA live countdown to a moment
- Pro
Timecode Text
NumbersA running timecode, hours to frames
- Pro
Typing Indicator Text
DecorativeShow who is typing in a chat
- Pro
Status Pulse Text
DecorativeA live status beside a dot
Sliding Number
NumbersDigits that roll as the value changes