Skip to content

<View fixed> with position: absolute + bottom + auto-height triggers Yoga top overflow on long documents #3416

@hollicers

Description

@hollicers

Summary

A <View fixed> (or <Text fixed>) with position: absolute + bottom + auto-height (no explicit height) on a long enough document accumulates a per-page top value that eventually overflows PDFKit's ±1e21 numeric limit, throwing Error: unsupported number: -X.XXe+21 and aborting the render. The threshold depends on document length and content density — short documents render fine, longer ones crash.

This is the most-documented pattern for fixed footers / page numbers (see react-pdf.org/advanced "Dynamic content" + "Page wrapping" sections), so the failure mode is reachable through ordinary use.

Version

@react-pdf/renderer@4.5.1 (the latest published as of filing). Companion package versions:

  • @react-pdf/pdfkit@5.1.1
  • @react-pdf/render@4.5.1
  • @react-pdf/layout@4.6.1
  • @react-pdf/primitives@4.3.0

Node 20+, server-side render via renderToBuffer. Reproduces both locally (Windows + macOS) and on Vercel.

Minimal reproduction

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

const styles = StyleSheet.create({
  page: {
    padding: 56,
    fontSize: 11,
    lineHeight: 1.5,
  },
  filler: {
    marginBottom: 12,
  },
  footer: {
    position: 'absolute',
    bottom: 36,
    left: 56,
    right: 56,
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingTop: 8,
    borderTopWidth: 0.5,
    borderTopColor: '#cccccc',
  },
  footerText: {
    fontSize: 8,
    color: '#666666',
  },
});

// Generate enough content to span ~20+ pages of natural-flow text.
const lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' +
  'Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ';
const FILLER = Array.from({ length: 400 }, () => (
  <Text key={Math.random()} style={styles.filler}>{lorem.repeat(8)}</Text>
));

const Doc = () => (
  <Document>
    <Page size="LETTER" style={styles.page}>
      {FILLER}
      <View style={styles.footer} fixed>
        <Text style={styles.footerText}>CASE-REF</Text>
        <Text
          style={styles.footerText}
          render={({ pageNumber, totalPages }) =>
            `Page ${pageNumber} of ${totalPages}`
          }
        />
        <Text style={styles.footerText}>Attribution</Text>
      </View>
    </Page>
  </Document>
);

(async () => {
  const buffer = await renderToBuffer(<Doc />);
  console.log('rendered', buffer.length, 'bytes');
})();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions