@beeq/react/ssr, the React SSR wrapper for BEEQ web components.
This setup lets you keep the benefits of Next.js server rendering while still using the same BEEQ React components in server and client components.
@beeq/react/ssr uses Stencil’s SSR-aware output target, which pre-renders component HTML on the server and hydrates it correctly on the client. The standard @beeq/react package marks every component 'use client', which means components render as empty shells during server rendering and can trigger React hydration mismatch warnings. The /ssr export avoids both of those issues.SSR-friendly components
Render BEEQ components in Next.js using
@beeq/react/ssr, including in server components.Client-only initialization
Configure icon asset paths in a small client component instead of turning your whole app into client-rendered React.
Same React API
Keep the familiar
BqButton, BqInput, and onBq... patterns from the React wrapper.If your project is a client-rendered React app without Next.js server rendering, use the dedicated React guide instead.
Why @beeq/react/ssr?
There are three reasons to use the wrapper rather than raw bq-* custom elements or the standard @beeq/react package in Next.js:
Data serialization. Without the wrapper, React serializes every prop passed to a custom element as an HTML attribute string. The wrapper handles the conversion between React props and the underlying DOM properties correctly, including non-primitive values like arrays and objects.
Event handling. React’s synthetic event system cannot listen to DOM custom events fired by web components without a manual addEventListener call. The wrapper maps onBqClick, onBqChange, onBqInput, and every other BEEQ event to the correct DOM listener automatically.
Server rendering. @beeq/react marks every component 'use client', which means they produce empty HTML during server rendering and can cause React hydration mismatch warnings in Next.js. @beeq/react/ssr pre-renders the component HTML on the server and hydrates it on the client, keeping Next.js server rendering intact.
Get started
You can add BEEQ to a Next.js app in a few steps:Check your project setup
Make sure your project already has:
- Next.js with React
18or19 - Node.js
18+ - a working Next.js application
Install the packages
Install the core package, the React wrapper, and the copy plugin used in the icon setup example:What each package gives you:
@beeq/coreincludes the web components, styles, icons, and shared types@beeq/reactincludes both the standard React wrapper and the SSR-ready exportscopy-webpack-plugincopies SVG assets intopublicduring the Next.js build
Configure icons
Easiest setup: use the CDN
Many BEEQ components rely on SVG icons. Your application needs to serve the SVG files and tell BEEQ where to find them.The quickest approach is to add a<script> tag with a data-beeq attribute directly inside the <html> element in your root layout.tsx, before <body>:app/layout.tsx
Alternative setup: copy SVGs into public
Alternatively, you can copy the SVG files into your public directory during the build and set the base path in a client component.
This approach is more work but gives you control over the SVG files and avoids external dependencies.Copy the SVG files into public/icons/svg during the build:next.config.ts
Create a client component to set the base path
If you chose the copy approach, you need a component that callssetBasePath("/icons/svg") on the client to tell BEEQ where to find the icons.
The component uses a dynamic import inside useEffect so setBasePath() only runs in the browser, never during server-side rendering.
The isInitialized flag then prevents children from rendering before the path is set, avoiding a race condition where BEEQ tries to load icons before initialization has completed.BeeqSetup in pages/_app.tsx so it runs on every page:pages/_app.tsx
Next.js usage patterns with BEEQ
Use 'use client' only where interactivity is needed
Server components can render static BEEQ UI, but event handlers and React hooks still belong in client components:
Slots still use the slot prop
Slotted children use the slot prop, the same as in standard React usage:
TypeScript notes
BEEQ exports typed custom event interfaces from@beeq/core. Use them when you need explicit types in extracted handlers or more complex event payloads:
event.detail.value — this is Stencil’s convention for custom event payloads. Avoid event.target.value directly, as it may not reflect the component’s latest internal state in all cases.
See the React guide TypeScript notes for more examples.
Troubleshooting
Icons are not rendering
Icons are not rendering
Check both of these:
- the SVG files are available from a public URL in your Next.js app
setBasePath()runs on the client and points to that same public URL
My page became a client component unexpectedly
My page became a client component unexpectedly
Keep your
BeeqSetup component separate and render it near the root. Only add 'use client' to files that truly need hooks, browser APIs, or event handlers.Event handlers are not working
Event handlers are not working
Event handlers such as
onBqClick must live in client components. Server components can render the markup, but they cannot attach browser event handlers.I am importing from @beeq/react and not @beeq/react/ssr
I am importing from @beeq/react and not @beeq/react/ssr
In plain React apps that is fine, but in Next.js you should prefer
@beeq/react/ssr so the wrapper can participate correctly in server-rendered output.Styles are missing
Styles are missing
Make sure
@beeq/core/dist/beeq/beeq.css is imported once in app/globals.css or the global stylesheet your app actually loads.Does BeeqSetup's 'use client' affect my server components?
Does BeeqSetup's 'use client' affect my server components?
No. When One trade-off: the
BeeqSetup wraps {children} and those children are passed in from a server-component parent (layout.tsx), Next.js pre-renders the children on the server independently. The 'use client' boundary applies only to BeeqSetup itself — not to the children passed into it as a prop:isInitialized guard means children appear after the client-side effect fires, so the initial SSR HTML is empty. For pages where initial HTML matters (SEO, LCP), replace null with a skeleton or render children unconditionally and accept the brief icon-less state.Next steps
Explore components
Start with a component page to see props, events, slots, and framework examples.
Customize the theme
Review theming options if your product needs brand customization.
Open Storybook
Explore component states and interactions in the live component library.