Skip to content
Get started

Components

Comment

Unstable: one comment in a discussion, who, when and what, with Like and Reply buttons and its replies indented under it. Import it from @nizivo/react/unstable/comment.

Server component, no client JSUnstable

Examples

Basic

A comment with a reply under it.

Priya Raman
Could we try the sage glaze on the hero shot? It reads warmer next to the candles.
Jonah Okafor
Agreed — I’ll reshoot it this afternoon.
import type { JSX } from 'react';
import { Avatar } from '@nizivo/react/avatar';
import { Comment } from '@nizivo/react/unstable/comment';

export function CommentExample(): JSX.Element {
  return (
    <div style={{ maxInlineSize: 480 }}>
      <Comment
        author="Priya Raman"
        avatar={<Avatar name="Priya Raman" decorative />}
        time={
          <time dateTime="2026-10-28T07:41" title="28 October 2026, 07:41">
            2 h ago
          </time>
        }
        likes={12}
        replyable
        replies={
          <Comment
            author="Jonah Okafor"
            avatar={<Avatar name="Jonah Okafor" decorative />}
            time={
              <time dateTime="2026-10-28T08:05" title="28 October 2026, 08:05">
                1 h ago
              </time>
            }
            likes={3}
            liked
            replyable
          >
            Agreed — I’ll reshoot it this afternoon.
          </Comment>
        }
      >
        Could we try the sage glaze on the hero shot? It reads warmer next to the candles.
      </Comment>
    </div>
  );
}

Import

import { Comment } from '@nizivo/react/unstable/comment';

// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/comment.css';

Static or interactive

Server. No client JavaScript: Like and Reply call onLike and onReply. How to choose.

Content

author names the writer and avatar takes an Avatar, decorative since the name is printed beside it. time is best a <time> with the full date as its title. likes adds Like, a toggle (liked) named with its count ("Like, 12"); replyable adds Reply. replies holds more Comments, indented under this one. Each comment is an <article>.

Props

Server component Renders data-slot="comment" with the class nz-comment. Props: CommentProps. Source: src/unstable/comment/comment.tsx.

NameTypeDefaultDescription
authorrequiredReactNode–

Who wrote it.

avatarReactNode–

An Avatar of the author; decorative, since the name is printed beside it.

childrenrequiredReactNode–

The comment.

labelsPartial<CommentLabels>–
likedbooleanfalse

Whether the reader liked it (the toggle's aria-pressed).

likesnumber–

How many likes. Without it there is no Like button.

localestring'en-US'

BCP 47 tag for the count.

onLike() => void–
onReply() => void–
renderRenderProp<Record<string, never>>–

Must render an <article>.

repliesReactNode–

Replies, indented under this comment: more Comments.

replyablebooleanfalse

Adds the Reply button.

timeReactNode–

When: a <time> with the full date as its title.

  • Also takes every attribute of <article> except children. (Omit<ComponentPropsWithRef<"article">, "children">)

render takes an element, or, in client code, a function of the props and no state.

Other exports

CommentLabels type

import type { CommentLabels } from '@nizivo/react/unstable/comment'

Comment's own strings (§16.4): serialisable, English defaults.

NameTypeDefaultDescription
likerequiredstring'Like, {count}'

The Like button's name: {count} is the likes.

replyrequiredstring'Reply'
CommentProps type

import type { CommentProps } from '@nizivo/react/unstable/comment'

The props of Comment, listed above.

Data attributes and slots

Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.

SlotRendered byData attributes
comment
.nz-comment
Comment
root (takes render)
none
comment-action
.nz-comment-action
Comment
inner element (CSS only); interactive, focus: self
none
comment-action-text
.nz-comment-action-text
Comment
inner element (CSS only)
none
comment-author
.nz-comment-author
Comment
inner element (CSS only)
none
comment-body
.nz-comment-body
Comment
inner element (CSS only)
none
comment-replies
.nz-comment-replies
Comment
inner element (CSS only)
none

CSS hooks

Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.

This stylesheet reads no public hook.

Layers: nz.components. Classes: .nz-comment, .nz-comment-action, .nz-comment-action-icon, .nz-comment-action-text, .nz-comment-actions, .nz-comment-author, .nz-comment-avatar, .nz-comment-body, .nz-comment-header, .nz-comment-replies, .nz-comment-time.

Tokens this stylesheet reads (15)

--nz-font-body-m, --nz-font-body-s, --nz-font-label-m-strong, --nz-font-label-s, --nz-icon-critical, --nz-radius-xs, --nz-size-icon-sm, --nz-space-0-5, --nz-space-1-5, --nz-space-2, --nz-space-4, --nz-space-6, --nz-space-8, --nz-text-primary, --nz-text-secondary

Accessibility

These parts are interactive. Each gets the focus outline and touch-action rule from @nizivo/react/css/base.css (the nz.base layer), so the floor survives a restyle:

  • comment-action: draws the focus outline itself on keyboard focus.

Keyboard

To be written.

On this page