Component architecture
Code components run as isolated React applications. Each one mounts in its own Shadow DOM container with a separate React root, creating a sandboxed environment that prevents conflicts with the main page or other components.
Because of this isolation, each imported React component manages its own dependencies, state, and context. When building, it’s important to consider how your components handle state and communicate with each other.
Key concepts
- Shadow DOM isolation - Styles and DOM elements are contained.
- Separate React roots - No shared state or context between components.
- Server-side rendering - SSR provides initial HTML
- Client-side execution - All interactivity runs in the browser
This architecture affects how you handle state management, component communication, data fetching, and styling. Use the following patterns to manage these constraints when building your React components for import into Webflow.
Shadow DOM and React roots
Each code component runs in its own Shadow DOM container with a separate React root. This sandboxed environment prevents conflicts with the main page and other components:
- Your component’s styles won’t leak to the page
- Page styles won’t override your component’s styles
- You must explicitly import external styles (site variables, tag selectors, etc.)
Composing components with slots
When composing code components using slots, parent and child components may not share state through React context. Each child component renders in its own Shadow DOM container, which isolates component state sharing.
Shadow DOM impacts how you style components as well as your ability to use third-party libraries. To learn more about styling components within the Shadow DOM, see the styling components guide and frameworks and libraries guide.
Server-side rendering (SSR)
Webflow supports server-side rendering (SSR) for code components. SSR generates initial HTML for the component on the server, which can improve perceived performance and SEO. After the page loads, Webflow automatically hydrates the component in the browser so that it becomes fully interactive.
Webflow enables SSR by default, but you can disable it by setting ssr
to false
in the component’s definition file.
When to disable SSR
You’ll want to turn off SSR for code components that rely on client-only behavior or that don’t benefit from server-rendered HTML. Common cases include:
- Browser APIs: Components that use window, document,
localStorage
, or other APIs not available during SSR. - Dynamic or personalized content: User-specific dashboards, authenticated views, or components that need client data to render correctly.
- Heavy or interactive UI: Charts, 3D scenes, maps, or animation-driven elements that would bloat the server-rendered HTML and be re-rendered anyway.
- Non-deterministic output: Anything that renders differently on the server vs. client (for example, random numbers, time-based values).
If the HTML output helps with SEO or improves the first paint, keep SSR on. If the component is purely interactive, client-specific, or browser-dependent, disable SSR.
React Server Components are not supported
React Server Components aren’t supported in code components. All code components must use standard React components.
Communicating between components
Because each code component runs in its own React root, they can’t share React Context or state directly. Instead, use one of the following patterns to manage state across multiple components.
Sharing state across components
URL parameters
Store state in the URL using URLSearchParams
for shareable, bookmarkable state. This is useful for search queries, filters, navigation state, or pagination.
Browser storage
Use localStorage
for persistent data or sessionStorage
for session-only data. Only store non-sensitive information since this data is visible to users.
Best for: user preferences, form data, temporary state.
Nano Stores
Nano stores is a lightweight state management library for cross-component communication, and is a useful alternative to React Context for sharing state between components.
Using Nano Stores
Install Nano Stores
In your React project, install Nano Stores by running the following command in your terminal:
Create a store
A store represents is external shared state: any component can access, modify, or subscribe to it. Create a file to create the store. Use Nano Stores’ atom()
to make a shared, reactive variable.
Note: This example uses an atomic store with a single value. See the Nano Stores documentation for more information on the different types of stores.
Custom events
To notify a component of an event or update another component, use custom events to communicate across React components in Webflow:
Data fetching
Code components support client-side data fetching. This means your React component can request live or real-time data from a public API after it renders in the browser.
To fetch data, use React’s useEffect
hook when the component mounts:
Key considerations
- Public APIs only: Never include secrets or sensitive API keys in your component code. All JavaScript runs in the browser and is visible to users.
- CORS support required: The API must accept cross-origin requests from your Webflow-hosted site.
- No environment variables:
.env
files aren’t supported. If you need to pass configuration values (like endpoint URLs, IDs, or feature flags), provide them as props instead of embedding them directly.