Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use server rendering for the page, then isolate custom-element registration and browser interaction in a small client boundary. In Next.js App Router, keep the route and data work in Server Components, load the element definition on the client, and verify the element’s attribute, property, and event contract against the exact React and framework versions you deploy. React 19 supports custom elements, but its server-rendering rules differ from its client-rendering rules.

What a custom element contributes

A custom element is a browser-recognized HTML tag whose behavior is registered with CustomElementRegistry.define(). Autonomous custom elements extend HTMLElement, and their names must contain a hyphen, such as user-card. An element can observe markup attributes with observedAttributes and attributeChangedCallback().

Define the element before code expects its behavior, but do not make browser-only globals an eager dependency of server-rendered modules. Import the definition where it is needed on the client, and make registration idempotent if a module might be evaluated more than once:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
if (!customElements.get('user-card')) {
  customElements.define('user-card', UserCard);
}

Autonomous elements are generally the safer choice for broad browser support. MDN notes that Safari does not plan to support customized built-in elements. See MDN’s custom-elements documentation.

#1 Best Overall
Portable Rolling Over Bed Laptop Desk, Adjustable Height and Tilt for Home
  • Versatile Dual Large-Surface Desk:A 25" × 12.99" workspace. This portable and overbed desk features a flexible layout, designed to hold office essentials like your laptop, popcorn, and coke for a spacious, mobile workstation. It allows you to work from anywhere at home, enhancing your daily living experience
  • Height & Angle Adjustable with Easy Mobility : Height adjustable from 17.05" to 29.72" for seated or standing work. The flexible design allows use anywhere at home without compatibility concerns. The desktop tilts and swivels to find your perfect angle, enhancing comfort. It rolls effortlessly on four casters for easy repositioning and convenient access during use
  • Upgraded Alloy Steel Frame and Quadrilateral Stable Base: Market's latest structure with alloy frame and reinforced base eliminates wobbling, ensures 10+ years durability. Locking casters and reinforced fasteners provide reliable stability, while this breakthrough construction offers exceptional strength and durability surpassing competing products
  • Latest 2025 Model with Ergonomic Design: Data-driven ergonomics provide perfect adult working height. Anti-slip stoppers lock items in place at any tilt. A space-saving hero that transforms tight spaces into efficient workstations anywhere. As the most innovative product of 2025, it is designed to meet everyone's needs
  • Quick Tool-Free Assembly: The included instructions allow for quick and easy assembly. Dedicated support is always available if needed. For any questions or issues, please contact us through your order, and we are here to help. This product is protected by intellectual property rights

How do I use web components in Next.js?

Next.js App Router pages and layouts are Server Components by default. They can fetch data, render HTML, and stream the result, but they should not assume browser APIs. A Client Component is the boundary for state, event handlers, lifecycle code, and browser APIs. The 'use client' directive marks a client entry point; files imported below that entry point do not each need the directive, and props crossing the boundary must be serializable. Read the Server and Client Components guide and use client reference.

A practical arrangement keeps most of the page on the server and gives only the custom element a client wrapper:

// app/profile/page.tsx (Server Component)
import UserCardClient from './UserCardClient';

export default async function Page() {
  const user = await getUser();
  return (
    <main>
      <h1>Profile</h1>
      <UserCardClient name={user.name} />
    </main>
  );
}
// app/profile/UserCardClient.tsx
'use client';

import { useEffect } from 'react';

export default function UserCardClient({ name }: { name: string }) {
  useEffect(() => {
    void import('./user-card.js');
  }, []);

  return <user-card name={name} />;
}

This keeps unrelated route content as server output while the element’s definition and interaction stay client-side. The boundary is an architectural choice based on Next.js capabilities, not a measured performance guarantee.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
TigerDad Mobile Adjustable Height Laptop Stand PC Computer Portable Notebook Swivel Laptop Desk Rolling Table Desk Cart Tiltable with Wheels Casters& Mouse Pad Table (Wood)
  • TILTABLE SPLIT DESKTOP & CUSTOM COMFORT--Tailor your workstation to your exact needs. Features a dual-panel design with a 15"L x 12"W main tiltable table and 8"L x 12"independent mouse pad station. Easily adjust the panel to any ergonomic angle and lock it firmly in place to reduce neck strain, whether you are typing, reading, or drawing in bed.
  • INFINITE HEIGHT ADJUSTABILITY --Transition seamlessly from sitting to lounging. Designed with a flexible single-pole single-frame mechanism, this mobile laptop desk can be smoothly raised or lowered from 23" to 33". Find your perfect, personalized posture next to low-profile sofas, standard platform beds, or cozy dorm recliners with a simple, effortless adjustment.
  • SAFETY ROLLING DESK WITH EDGE STOPPER--Work with absolute peace of mind. Equipped with a built-in safety edge stopper, this bedside table securely anchors your laptop, tablet, or notebooks, preventing them from sliding off even when the desktop is tilted at maximum angles. Keep your expensive electronics safe while enjoying breakfast or drafting emails.
  • STURDY E1 MDF PANEL & WELDED FRAME--Built to last, engineered for safety. Crafted from premium, water-resistant 15mm E1-grade MDF board and backed by a thickened, heavy-duty welded metal frame, this over bed desk proudly supports up to 30 lbs of evenly distributed weight. Experience rock-solid stability with a modern wood-grain look that seamlessly fits any home decor.
  • 360° SMOOTH MOBILITY & EASY ASSEMBLY--Roll it anywhere you want, lock it whenever you need. Features 4 heavy-duty 1-inch rolling casters with built-in stop plugs for effort-free movement and rock-solid still-standing

Can I use custom elements with server-side rendering?

Yes, but distinguish server-emitted markup from browser upgrades. The server can emit a custom tag and primitive attributes as HTML. The browser later registers the element, upgrades it, and runs its implementation. Whether the element has useful pre-hydration content depends on its design: light-DOM fallback or server-rendered children can remain meaningful, while behavior requiring browser APIs must wait for the client.

React’s documented custom-element behavior is version-specific. React 19’s release announcement says, “React 19 adds full support for custom elements and passes all tests on Custom Elements Everywhere.” See React 19. Do not assume that statement describes every older React release or every non-React SSR framework.

How does React 19 pass values during SSR?

React treats attributes as markup-visible strings and properties as arbitrary JavaScript values. During React 19 SSR, primitive props such as strings, numbers, and true are emitted as attributes. Non-primitive values (including objects, symbols, and functions), and false, are omitted from the server HTML. On the client, if the prop name matches a property on the custom-element instance, React assigns that property; otherwise it assigns an attribute. These rules are documented in React 19.

Rank #3
Sale
BUYIFY 23.4" Foldable Lap Desk Bed Table with Cup Holder Tray Black
  • PERFECT FOLDABLE DESIGN: 23.43"(L)x15.75"(W)x9.25"(H).This laptop bed desk is designed to be foldable, allowing you to easily open the table legs for use without any assembly. When not in use, simply fold it in half for compact storage, saving space in your room.
  • CONVENIENT CUP HOLDER AND TABLET SLOT: Features a built-in cup holder to securely hold your drink and a stand groove to keep your tablet, or phone upright, making it easy to enjoy your favorite shows or work hands-free.
  • MULTI-FUNCTIONAL: This laptop table is designed for versatility.Ideal for various activities like working, studying, reading, eating, or watching movies. Perfect for use on the bed, sofa, floor, balcony, or even outdoors. Can be used as a laptop desk, dining tray, mini writing desk, or picnic table.
  • ERGONOMIC AND SPACIOUS DESIGN: The desk dimensions are designed for comfort, providing ample space for laptops, books, or meals. Enjoy an ergonomic setup whether you’re sitting cross-legged on the sofa or lying comfortably in bed.
  • EASY TO STORE AND PORTABLE: With its lightweight design, this foldable laptop desk can be easily carried from room to room or taken on outdoor trips. After use, fold it up and store it next to the sofa or under the bed without taking up much space.
Value or need Server result in React 19 Recommended integration
String, number, or true Rendered as an HTML attribute Use an attribute when the element’s contract expects a string-like setting
false Omitted from SSR markup Define the element’s default explicitly; do not rely on a false-valued server attribute
Object, symbol, or function Omitted from SSR markup Assign the instance property on the client
Custom event No server listener Attach a client listener using the element’s documented event name

For example, primitive configuration can be written directly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<date-picker locale="en-US" disabled={true} />

An object-valued property needs client-side assignment. A ref-and-effect wrapper makes that timing explicit:

'use client';

import { useEffect, useRef } from 'react';

export default function ChartElement({ options }) {
  const ref = useRef(null);

  useEffect(() => {
    if (ref.current) ref.current.options = options;
  }, [options]);

  return <data-chart ref={ref} />;
}

The element must actually expose an options property; React cannot infer a universal property contract. Use TypeScript declarations or a wrapper when your project needs stronger checking.

Rank #4
Sale
SAIJI Height & Angle Adjustable Lap Desk Laptop Stand for Bed
  • Ergonomic Design Bed Desk - Soft wrist rest pad provides your wrist a comfortable place. The retractable blocker protects your computer from falling down. 5 adjustable heights(9.4"-12.6") and 4 adjustable angles (0-36°) provide you a more comfortable posture and avoid back & neck pain.
  • Multi-Usage Bed Desk – You can use it easily as a laptop workstation / study solution for college dorm and nursing school essentials for girls and guys /laptop table for bed/children's bed table/mini writing table/standing table for office work/laptop couch table/book/tablet table.
  • Stable and Sturdy Laptop Bed Desk: The SAIJI laptop table panel is made of durable wood, which is long lifespan and not easy to break. The table legs are made of high-quality metal which can hold up to 80 pounds of weight. It won’t collapse and break.
  • Foldable and Portable Laptop Desk for Bed: SAIJI Laptop desk for bed can be folds flat for space-saving storage. It’s only 1.8 inches thick after folded, so it’s easy to carry and storage. Great for using at home, office or on the road.
  • Satisfied customer service: Any question about our SAIJI lap desks bed trays,ss please feel free to contact us via e-mail at first time. SAIJI customer service team will give you a satisfied solution and professional customer service support.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How do I pass props and events to a web component in React?

Start with the element author’s contract. Put string-like values in attributes, and pass complex JavaScript data through a property after the element exists. React’s DOM documentation describes custom events with an on-prefixed JSX prop, for example:

'use client';

export function SearchBox({ onResult }) {
  return (
    <site-search onsearchresult={onResult} />
  );
}

Use the exact event name emitted by the element. A payload is commonly available as event.detail, but that is only correct when the element documents that shape:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function handleResult(event) {
  const result = event.detail;
  // consume the element's documented payload
}

<site-search onsearchresult={handleResult} />

For elements whose event naming or property behavior does not map cleanly to JSX, attach listeners and properties through a ref in an effect. This also gives you a single place to remove listeners during cleanup.

Best Value
KLSMYHOKI Standing Desk Adjustable Height, Mobile Stand Up Desk with Wheels
  • 【Adjustable Height Standing Desk】Adjustable height 27"-43.5", you can keep your favorite height. You can sit or stand, 31.5" x 16" tabletop for more storage space.
  • 【Ergonomic Home Office Desk】The change between sitting and standing helps you relieve fatigue, avoid health problems of sitting and improve work efficiency, standing desk can improve posture, relieve back and neck pain, provide you with more healthy work position.
  • 【Portable Mobile Standing Laptop Desk】4 flexible lockable wheels make the mobile standing desk move where you want, each wheel is equipped with a locking lever so you can hold the desk securely when needed placed in an appropriate location.
  • 【Sturdy and Stable Table】Double supports the desktop, even if a 180-pound adult sits on the table, the height of the table will never slip. The table is made of heavy-duty steel, and the middle of the two frames is equipped with a thickened steel frame, which is very stable and is An alternative to standard office and computer desks.
  • 【Friendly Customer Service】We provide 7*24 hours after-sales service, 90-day risk-free money-back guarantee, if you have any questions during use, please feel free to contact us, we will provide you with a satisfactory solution.

Why does my custom element cause a hydration mismatch?

Hydration attaches behavior to HTML that was already rendered. The browser’s first React render must agree with the server HTML. Registration timing, browser-only API calls, random values, dates, or a client-only branch that changes the initial markup can violate that requirement. Next.js documents the failure mode and remedies in “Text content does not match server-rendered HTML”.

Keep the initial tree deterministic

  • Render the same custom-element tag, attributes, and fallback children on the server and on the first client render.
  • Import the element definition and read browser globals inside client lifecycle code, not while a server module is evaluated.
  • Do not make registration itself change the initial React markup.
  • Preserve light-DOM fallback content when the element supports it, so users have useful HTML before upgrade.

Use an intentional browser-only boundary when necessary

If a component cannot render safely on the server, make that choice explicit. Next.js documents disabling prerendering for such a component as one option. The trade-off is that the component’s useful HTML is delayed until the browser, so use this for genuinely browser-dependent widgets rather than as a default workaround.

suppressHydrationWarning is a narrow escape hatch for unavoidable text differences. Next.js notes that it works only one level deep and does not repair mismatched markup; it is not a general custom-element integration strategy.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which integration strategy fits?

Strategy Useful when Cost or risk
Server-rendered tag plus client upgrade The element has meaningful fallback or light-DOM content Registration and browser behavior still arrive later
Client-only rendering The element cannot produce stable server output or requires browser APIs immediately No element HTML is available until hydration/client rendering
Direct JSX usage React 19’s property and event behavior matches the element contract Complex values and unusual events may need explicit handling
Small React wrapper You need ref-based property assignment, event cleanup, or TypeScript types Additional code, but a narrower and clearer contract
Global eager registration The element is needed throughout a browser-only application Can pull browser-only code into server paths or register twice
Client-side or lazy registration The element appears on selected routes or should load only when needed Behavior is unavailable until the client import runs

How should this be adapted to another SSR framework?

The principles generalize: server code must not assume browser globals, and hydration requires a stable initial result. The detailed custom-element SSR rules above are React 19 rules, while the framework-specific boundary examples are Next.js App Router guidance. A different React SSR framework may use different render and hydrate APIs; verify its React version and integration docs. A non-React framework has its own serialization, island, hydration, and event semantics, so do not promise that React JSX behavior applies there.

Deployment checklist

  • Confirm the custom name contains a hyphen and the definition uses customElements.define().
  • Ensure the definition module is not evaluated on the server when it references window, document, or other browser-only globals.
  • Guard registration with customElements.get() when duplicate evaluation is possible.
  • Keep the Next.js server/client boundary close to the element and pass only serializable props across it.
  • Classify every input as an attribute or an instance property; test object values on the client.
  • Use the event name and payload shape documented by the element, rather than assuming event.detail.
  • Compare server HTML with the first browser render before relying on hydration.
  • Test with the exact Next.js, React, and component-library versions used in production.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.