最初のページを作る
React アプリに Imposia を追加し、HTML を A4 ページとして表示して、印刷または PDF 保存までつなげます。
このガイドでは、既存の React アプリにページ分割されたプレビューを追加します。終える頃には、同じコンポーネントで HTML を A4 ページとして表示し、紙または PDF への出力に向けてブラウザー標準の印刷フローを開けるようになります。
始める前に
React 18 以降と、クライアントサイドのブラウザー環境が必要です。Imposia は Node.js やサーバーサイドレンダリング中にはページを生成しないため、フレームワークのクライアント境界より内側でマウントしてください。
React パッケージをインストールする
pnpm add @imposia/react react react-domパッケージのスタイルシートは、このコンポーネントまたはアプリのクライアントエントリーファイルで一度だけ読み込んでください。複数回読み込んでも害はありませんが、読み込みを忘れると Viewer にスタイルが当たりません。
ページ文書を表示する
import { ImposiaPageViewer, type ImposiaPageViewerHandle } from "@imposia/react";
import { useRef } from "react";
import "@imposia/react/styles.css";
export function Preview() {
const viewer = useRef<ImposiaPageViewerHandle>(null);
return (
<>
<ImposiaPageViewer
ref={viewer}
source={{ html: "<article><h1>こんにちは</h1><p>ブラウザーネイティブなページ。</p></article>" }}
documentOptions={{ page: { size: "A4", margin: "18mm" } }}
/>
<button type="button" onClick={() => void viewer.current?.print()}>
印刷 / PDF 保存
</button>
</>
);
}source.html にはページ分割する内容を、documentOptions.page には用紙サイズと余白を指定します。ハンドルは常に、直近でページ分割に成功した文書を指します。作成途中の文書を指すことはありません。
結果を確認する
ブラウザーでコンポーネントを開くと、HTML が Viewer 内に A4 ページとして表示されます。
印刷 / PDF 保存をクリックすると、表示中のページに対してブラウザー自身の印刷ダイアログが開き、読者はそこでプリンターまたはPDF に保存を選びます。このメソッドはダイアログを起動した時点で解決し、PDF バイトは返しません。
進行状況と失敗を表示する
上の例は静的な文字列を描画するため、ほぼ即座に確定します。実際のソースには時間がかかります。画像やフォントの読み込みが終わるのを待ち、長い文書は多くのページへ分割されます。その処理の進行を表示したいときは useImposiaDocument を使います。
import { useImposiaDocument } from "@imposia/react";
export function Preview({ html }: { html: string }) {
const { hostRef, state } = useImposiaDocument({ source: { html } });
return (
<>
{state.status === "loading" && <p role="status">ページを準備しています…</p>}
{state.status === "error" && <p role="alert">この文書をページ分割できませんでした。</p>}
<div ref={hostRef} />
</>
);
}state.status は idle、loading、ready、error のいずれかです。初回成功後の loading は、次の版を準備しながら以前のページを表示し続けている状態を表します。スピナーはプレビューを置き換えるのではなく、プレビューの横に置いてください。state.status が error のときも、表示されているのは最後に成功した文書のままです。
EPUB の書き出し(任意)
製品に意味構造を保ったリフロー型の成果物も必要なら、同じ確定済み文書から EPUB 3.3 Blob を作れます。これは副次的な出力で、上のプレビューと印刷の経路には含まれません。不要なら読み飛ばしてかまいません。
メタデータは必須です。title、language、identifier がないと、書き出しは reject されます。
const blob = await viewer.current?.exportEpub({
metadata: { title: "こんにちは", language: "ja", identifier: "urn:example:hello" },
});このメソッドは Blob を返します。ダウンロードやアップロードにつなぐのはアプリケーションの役割です。EPUB はページ分割後のページ DOM ではなく意味構造を保つソースから作られるため、ページ装飾と生成されたページ番号は意図的に含まれません。