Skip to content

feat(examples): add runnable Next.js App Router example (#21)#52

Open
rajarshidattapy wants to merge 1 commit into
unlayer:mainfrom
rajarshidattapy:example/nextjs-app-router
Open

feat(examples): add runnable Next.js App Router example (#21)#52
rajarshidattapy wants to merge 1 commit into
unlayer:mainfrom
rajarshidattapy:example/nextjs-app-router

Conversation

@rajarshidattapy

Copy link
Copy Markdown

Summary

Adds a runnable Next.js 15 App Router example under examples/nextjs-app-router/ that renders an Elements email with renderToHtml() in a Server Component and previews it at /email-preview. Closes #21.

Changes

  • examples/nextjs-app-router/ — new example:
    • src/emails/welcome-email.tsx — a realistic transactional email as a props-driven component tree
    • src/app/email-preview/page.tsx — Server Component calling renderToHtml() + renderToPlainText(), previewing the result in an iframe
    • src/app/email-preview/raw/route.tsx — Route Handler serving the rendered HTML as text/html, the shape production code usually takes
    • README.md with setup instructions and the Server Component caveat
  • README.md (root) — new Examples section linking the example
  • pnpm-workspace.yaml — excluded the example; it has its own pnpm-workspace.yaml so pnpm install inside the directory installs the example alone (see Notes)

Test Plan

  • pnpm build passes
  • pnpm test passes (450 tests, 36 files)
  • Tested in Storybook — N/A, no library or UI-component change
  • Added/updated tests for new behavior — see Notes

Manually verified end to end:

cd examples/nextjs-app-router && pnpm install && pnpm dev

/ → 200, /email-preview → 200, /email-preview/raw → 200 text/html containing 33 tables and 54 Outlook conditional comments. Preview page checked in headless Chromium: email renders in the frame, no console or page errors. pnpm build in the example passes. Root pnpm install && pnpm build unaffected.

Notes

Why the example installs from npm instead of workspace:*. My first version was a workspace member. Both pnpm dev and next build --turbopack failed:

x You're importing a component that needs `createContext` …
x You're importing a component that imports react-dom/server …
  at ../../packages/react/dist/index.js

pnpm symlinks the workspace copy, Next resolves it to a path outside node_modules, compiles it as first-party source, and its RSC checks reject the barrel. serverExternalPackages: ["@unlayer/react-elements"] does not fix it — I tried; that list is matched against node_modules resolutions, which a symlinked workspace package no longer is.

Installing @unlayer/react-elements@^0.1.20 from npm lets Next externalise it on the server like any other dependency, and matches what a real consumer does. next.config.ts is empty as a result. The two workspace-config changes exist only to keep pnpm from re-linking the local copy.

Renders an Elements email to HTML inside a Next.js 15 App Router Server
Component and previews it at /email-preview.

- examples/nextjs-app-router/ — welcome email component tree, a Server
  Component calling renderToHtml() + renderToPlainText() into an iframe
  preview, and a Route Handler serving the raw HTML as text/html
- README with setup instructions, linked from a new Examples section in
  the root README

The example installs @unlayer/react-elements from npm rather than via
workspace:*. A symlinked workspace copy resolves outside node_modules, so
Next compiles it as first-party source and its RSC checks reject the
package's react-dom/server import and the provider's createContext —
`next dev` 500s and `next build` fails. serverExternalPackages does not
help; that list only matches node_modules resolutions. Installing from npm
lets Next externalise it on the server like any other dependency.

That required excluding the example from the workspace and giving it its
own pnpm-workspace.yaml, so `pnpm install` inside the directory installs
the example alone. Coverage against the local build is unchanged —
tests/nextjs-integration still packs the built tarball and runs next build
in CI.
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.

Example: Next.js App Router

1 participant