Skip to content

fix(react-pdf): draw a repeat container once in renderToBuffer - #366

Open
peter-cynomi wants to merge 1 commit into
vercel-labs:mainfrom
peter-cynomi:fix/react-pdf-repeat-container-once
Open

peter-cynomi wants to merge 1 commit into
vercel-labs:mainfrom
peter-cynomi:fix/react-pdf-repeat-container-once

Conversation

@peter-cynomi

Copy link
Copy Markdown

Problem

The server walk behind renderToBuffer, renderToStream and renderToFile draws a repeat container once per item. @json-render/react, and react-pdf's own provider Renderer, draw the container once and put every item's children inside it.

In the spec below, the outer section is repeated over /domains, and each domain has a nested Tasks section repeated over { "$item": "tasks" }. The server walk draws a different structure from React:

Line @json-render/react / provider Renderer renderToBuffer on main
Appendix B (outer repeat container title) once once per domain
Tasks (inner repeat container title) once per domain, including a domain with no tasks once per task, and none for the empty domain

The effects:

  • A repeat container with its own content, such as a section title or a table header, is duplicated in the PDF.
  • An empty repeat draws nothing, where React still draws the container.
  • React logs a missing key warning, because the per-item containers are returned in an unkeyed fragment.

Fix

The server walk now draws the container once, with each item's children in a keyed React.Fragment. Item keys still use repeat.key, falling back to the index.

Tests

packages/react-pdf/src/repeat-container.test.tsx runs a nested-repeat spec through both walkers and compares the order and count of the drawn lines. It also checks that an empty repeat draws its container once.

Both walkers pass on this branch. On main, the renderToBuffer cases fail and the provider Renderer cases pass. tsc --noEmit is clean and @json-render/react-pdf builds.

Note

This touches the same repeat block in render.tsx as #364, which filters repeat items by $item in visible. Whichever PR merges second will need a small rebase.

🤖 Generated with Claude Code

The server walk used by `renderToBuffer`, `renderToStream` and
`renderToFile` drew a repeat container once per item, so a container
with its own content (a section title, a table header) was repeated for
every item, and an empty repeat drew nothing. `@json-render/react` and
react-pdf's provider `Renderer` draw the container once and put every
item's children inside it.

Draw the container once in the server walk too, with each item's
children in a keyed fragment. This also removes React's missing `key`
warning for repeats.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

@peter-cynomi is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@peter-cynomi
peter-cynomi marked this pull request as ready for review September 29, 2026 10:40

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant