react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

fix: duplicated bookmarks when View is spanning multiple pages

Open rafw87 opened this issue 4 weeks ago • 1 comments

Fixes #1986.

Prevents cloning of bookmark prop when splitting node.

Current version: bookmarks-current.pdf

Fixed version: bookmarks-fixed.pdf

Code used to generate PDFs above:

import { Page, View, Text, Document } from "@react-pdf/renderer";

const SubChapter = ({ title }: { title: string }) => {
  return (
    <View style={{ gap: 8 }} bookmark={title}>
      <Text style={{ fontSize: 20, fontWeight: "bold", marginVertical: 24 }}>
        {title}
      </Text>
      <Text>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ornare
        augue urna, sed finibus ante congue quis. Vestibulum ultricies diam in
        diam tempus luctus. Phasellus vel lacus tortor. Nulla quam nisl,
        bibendum nec leo ut, hendrerit dignissim metus. Maecenas et nisl
        consequat, porttitor nisi a, commodo quam. Etiam sit amet est vel ligula
        hendrerit tempus. Sed eu nulla ac est maximus luctus.
      </Text>
      <Text>
        Phasellus est nibh, semper non magna eu, imperdiet ornare ante. Nam sit
        amet egestas lorem. Integer bibendum sagittis consectetur. Quisque
        scelerisque tincidunt ex id sollicitudin. Maecenas at dapibus leo. Ut
        volutpat elit et nulla elementum ornare. Cras interdum tempus maximus.
        Donec sodales sed turpis ut convallis. Cras non enim lobortis tellus
        facilisis ullamcorper sed quis mauris.
      </Text>
      <Text>
        Nunc efficitur nisi id augue hendrerit laoreet. Phasellus lectus sapien,
        dapibus sed sapien in, tempus cursus elit. Morbi vel condimentum quam.
        Nunc ligula diam, iaculis at rhoncus eu, fringilla sit amet ligula.
        Phasellus semper accumsan mi, et efficitur quam accumsan et. Integer
        maximus in ipsum a tempus. Curabitur velit arcu, pharetra a faucibus at,
        vestibulum at massa. Phasellus volutpat dictum mattis. Maecenas aliquam
        nisl sed dictum placerat. Aliquam scelerisque aliquet mi, nec volutpat
        tellus gravida id. Aliquam pretium rhoncus est, non vehicula elit rutrum
        ac. Mauris pellentesque sit amet dui in sollicitudin. Pellentesque
        habitant morbi tristique senectus et netus et malesuada fames ac turpis
        egestas. Proin ac volutpat odio, sed vehicula dolor. Praesent aliquet
        nec sem non luctus. Sed ligula lacus, dictum vitae mi ac, gravida
        faucibus justo.
      </Text>
      <Text>
        Etiam commodo odio ex, et ultrices ex blandit sit amet. Etiam lacus
        lorem, tempus vitae mi a, porttitor ullamcorper magna. Donec hendrerit
        risus elit, finibus commodo orci mollis non. Sed faucibus, diam sed
        imperdiet aliquet, nisl eros lacinia lacus, porttitor vulputate turpis
        massa at enim. Nunc ac velit metus. Nulla vel erat porttitor, pharetra
        quam facilisis, tempor ipsum. Ut eu nulla ac elit vehicula porttitor id
        at metus. Nullam eleifend tristique urna, id vestibulum elit laoreet eu.
        Maecenas non auctor quam. Maecenas at pretium neque. Donec sollicitudin
        non ipsum id auctor.
      </Text>
      <Text>
        Quisque iaculis lobortis diam vel consectetur. Sed quis massa eget diam
        imperdiet ultrices. Mauris convallis pellentesque ante sed bibendum.
        Nunc tincidunt, nisl sit amet dictum maximus, lorem sapien vehicula
        nibh, eget vestibulum lacus quam sed justo. Morbi est ante, sagittis
        tincidunt maximus ac, mollis sed ligula. Nam vestibulum luctus tellus,
        non pharetra mi facilisis at. Quisque turpis dui, vulputate at diam ac,
        volutpat dignissim velit. Duis a volutpat mi. Curabitur porta leo lorem,
        ut malesuada nisl condimentum eget. Morbi nibh turpis, pharetra ut
        eleifend eget, ultricies eu eros. Sed eget aliquet lectus.
      </Text>
    </View>
  );
};

const Chapter = ({ title }: { title: string }) => {
  return (
    <View bookmark={title}>
      <Text style={{ fontSize: 32, fontWeight: "bold", marginVertical: 24 }}>
        {title}
      </Text>
      <SubChapter title="Sub chapter 1" />
      <SubChapter title="Sub chapter 2" />
      <SubChapter title="Sub chapter 3" />
      <SubChapter title="Sub chapter 4" />
      <SubChapter title="Sub chapter 5" />
    </View>
  );
};

export const Test = () => {
  return (
    <Document>
      <Page size="A4" style={{ padding: 24 }} bookmark="Page">
        <Chapter title="Chapter 1" />
        <Chapter title="Chapter 2" />
        <Chapter title="Chapter 3" />
        <Chapter title="Chapter 4" />
        <Chapter title="Chapter 5" />
      </Page>
    </Document>
  );
};

rafw87 avatar Dec 05 '25 00:12 rafw87

🦋 Changeset detected

Latest commit: 3644fe9a77139f0f7dd8e0fda6848e114fa4d97b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@react-pdf/layout Patch
@react-pdf/renderer Patch
next-14 Patch
next-15 Patch
@react-pdf/vite-example Patch
@react-pdf/e2e-node-cjs Patch
@react-pdf/e2e-node-esm Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Dec 05 '25 00:12 changeset-bot[bot]