Integration

React / Next.js

Integrate NextReport into React and Next.js applications using the ReportViewer component.

Overview

The @nextreport/ui-viewer package provides a React component for rendering NextReport output in your application. It handles HTML display, scaling, and pagination.

Installation

npm install @nextreport/ui-viewer

The package has peer dependencies on react and react-dom >= 18.

ReportViewer component

The ReportViewer component accepts a report schema and data, renders the report, and displays the result:

import { ReportViewer } from '@nextreport/ui-viewer'

export function InvoicePage() {
  const report = {
    version: '1.0',
    type: 'report',
    page: { size: 'A4', orientation: 'portrait' },
    bands: [
      {
        type: 'header',
        height: 40,
        components: [
          {
            type: 'text',
            position: { x: 0, y: 10, width: 200, height: 20 },
            content: '{{title}}',
            fontSize: 18,
            fontWeight: 'bold',
          },
        ],
      },
    ],
  }

  const data = { title: 'My Invoice' }

  return <ReportViewer report={report} data={data} />
}

Props

PropTypeRequiredDescription
reportobjectYesReport schema object
dataobjectYesData context for expression evaluation
classNamestringNoCSS class for the container
scalenumberNoZoom level (default: 1.0)
pagenumberNoPage to display (default: 1)

Next.js App Router integration

In a Next.js App Router project, use the viewer as a client component:

// app/reports/[id]/page.tsx
import { ReportView } from './report-view'

export default async function ReportPage({ params }: { params: { id: string } }) {
  // Fetch report data server-side
  const res = await fetch(`${process.env.NEXTREPORT_URL}/api/templates/${params.id}`)
  const { template, sampleData } = await res.json()

  return <ReportView report={template} data={sampleData} />
}
// app/reports/[id]/report-view.tsx
'use client'

import { ReportViewer } from '@nextreport/ui-viewer'

interface Props {
  report: object
  data: object
}

export function ReportView({ report, data }: Props) {
  return (
    <div className="mx-auto max-w-4xl p-8">
      <ReportViewer report={report} data={data} />
    </div>
  )
}

Server-side rendering via API

For server-rendered HTML output, call the render API directly from a Server Component or API route:

// app/api/invoice/route.ts
import { NextResponse } from 'next/server'

export async function POST(request: Request) {
  const { templateId, data } = await request.json()

  const res = await fetch(`${process.env.NEXTREPORT_URL}/api/render`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ templateId, data, format: 'html' }),
  })

  const result = await res.json()
  return NextResponse.json(result)
}

PDF download

To offer PDF downloads, proxy the render API with format: 'pdf':

// app/api/invoice/pdf/route.ts
import { NextResponse } from 'next/server'

export async function POST(request: Request) {
  const { templateId, data } = await request.json()

  const res = await fetch(`${process.env.NEXTREPORT_URL}/api/render`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ templateId, data, format: 'pdf' }),
  })

  const pdf = await res.arrayBuffer()

  return new NextResponse(pdf, {
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'attachment; filename="invoice.pdf"',
    },
  })
}

Next steps