@tofu-dev/tofu-embed
v0.0.7
Published
React hook and Next.js helpers for Tofu personalization
Downloads
35
Maintainers
Readme
@tofu-dev/tofu-embed
React hooks and Next.js helpers for rendering Tofu personalization without flash or hydration issues.
Overview
This package makes an API call to Tofu's backend servers to fetch and replace content (text, images, and links) for personalized landing pages. API calls are only made when a visitor arrives with personalization parameters (?tofu_content_id=... and ?tofu_slug=...). For normal visits without these parameters, no calls are made.
Designed for React and Next.js:
- No flash of unpersonalized content - In Next.js, personalization happens before the page is visible, avoiding jarring content switches
- No hydration mismatches - Server and client rendering stay in sync, preventing React from reverting personalized content
How it works:
- In Next.js: Middleware forwards query parameters, the server fetches personalization data, and an inline script applies changes before React hydrates
- In React: The hook fetches data on mount and applies personalization client-side
- A mutation observer prevents React from overwriting personalized content during hydration
Requirements
- Node.js 18+
- React 18+
- Next.js 13+ App Router (only when you use the Next.js helpers)
Installation
npm install @tofu-dev/tofu-embed
# or
yarn add @tofu-dev/tofu-embedNext.js (App Router)
Forward Tofu query parameters in middleware:
// middleware.ts import { createTofuMiddleware } from "@tofu-dev/tofu-embed/server"; export const middleware = createTofuMiddleware();Add the script to your root layout:
// app/layout.tsx import type { ReactNode } from "react"; import { TofuScript } from "@tofu-dev/tofu-embed/server"; export default function RootLayout({ children }: { children: ReactNode }) { return ( <html lang="en"> <head> <TofuScript /> </head> <body> {children} </body> </html> ); }
Visit any page with ?tofu_content_id=123 and ?tofu_slug=landing to load the matching personalization before hydration. Analytics events are sent once per session by default.
Note: React may report hydration mismatches in development. This is expected when content is intentionally personalized before hydration. The package automatically patches those changes with a
MutationObserverto prevent reversion.
React (client only)
Call the hook once near the top of your tree. It reads ?tofu_content_id and ?tofu_slug, fetches personalization data, applies replacements, and sends analytics:
import { useTofuEmbed } from "@tofu-dev/tofu-embed";
export function App() {
useTofuEmbed();
return <RouterProvider />;
}