Frameworks and libraries

Learn how to use CSS frameworks and component libraries with code components.

Code components work with popular CSS frameworks and component libraries, though some require specific configuration for Shadow DOM compatibility. Below are setup patterns for common frameworks and libraries.

To use Tailwind CSS with your code components, configure PostCSS to process Tailwind classes:

1

Install Tailwind CSS

Install Tailwind CSS and its PostCSS plugin:

$npm install tailwindcss @tailwindcss/postcss postcss
2

Configure PostCSS

Add the Tailwind PostCSS plugin to your postcss.config.mjs file:

postcss.config.mjs
1export default {
2 plugins: {
3 "@tailwindcss/postcss": {},
4 }
5}
6
3

Import Tailwind styles

Import Tailwind in your main CSS file:

globals.css
1@import "tailwindcss";
4

Import styles in your component

Import your CSS file in each code component:

Badge.webflow.tsx
1import { Badge } from './Badge';
2import { props } from '@webflow/data-types';
3import { declareComponent } from '@webflow/react';
4
5import './globals.css'; // Import your styles
6
7export default declareComponent(Badge, {
8 name: 'Badge',
9 description: 'A badge with variants',
10 group: 'Info',
11 props: {
12 text: props.Text({
13 name: "Text",
14 defaultValue: "Hello World",
15 }),
16 variant: props.Variant({
17 name: "Variant",
18 options: ["Light", "Dark"],
19 defaultValue: "Light",
20 }),
21 },
22});
5

Use Tailwind classes

Now you can use Tailwind utility classes in your components:

Badge.tsx
1import * as React from "react";
2
3interface BadgeProps {
4 text: string;
5 variant: 'Light' | 'Dark';
6}
7
8export const Badge = ({ text, variant }: BadgeProps) => (
9 <span
10 className={`inline-block rounded-full px-3 py-1 text-sm font-medium ${
11 variant === 'Light'
12 ? 'bg-gray-100 text-gray-800'
13 : 'bg-gray-800 text-white'
14 }`}
15 >
16 {text}
17 </span>
18);

Shadcn/UI is a component library built on Tailwind CSS that provides pre-built, accessible React components. It works with code components but requires path alias configuration. Follow these steps after setting up Tailwind CSS:

1

Configure path aliases

Shadcn/UI uses path aliases that need to be configured in your webpack setup. Add this to your webpack configuration:

webpack.webflow.js
1module.exports = {
2 resolve: {
3 alias: {
4 "@": process.cwd(), // Maps @ to your project root
5 },
6 },
7};
8

For detailed webpack configuration options, see the bundling and deployment guide.

Style injection libraries

Libraries that inject styles into document.head (like Emotion, styled-components, or other CSS-in-JS solutions) won’t work inside Shadow DOM by default. Use the Shadow DOM provider pattern below to configure these libraries.

Material UI uses Emotion for CSS-in-JS styling. To use Material UI or similar libraries with code components, wrap your components in a Shadow DOM provider that allows Emotion to inject styles correctly.

Shadow DOM provider

ShadowDomProvider.tsx
1import React, { useEffect, useRef, useState } from "react";
2import createCache from "@emotion/cache";
3import { CacheProvider } from "@emotion/react";
4
5/**
6 * ShadowDomProvider - Wraps components to handle Emotion CSS-in-JS in Shadow DOM contexts
7 *
8 * This component creates an Emotion cache that can inject styles into Shadow DOM roots,
9 * which is essential for web components or isolated styling environments where
10 * traditional CSS injection into document.head won't work.
11 */
12export const ShadowDomProvider: React.FC<{ children: React.ReactNode }> = ({children}) => {
13 const ref = useRef<HTMLDivElement>(null); //access the DOM element and determine its root context
14 const [cache, setCache] = useState<any>(null);
15
16 useEffect(() => {
17 if (ref.current) {
18 const root = ref.current.getRootNode(); // Get the root node (could be ShadowRoot or Document)
19 const container = root instanceof ShadowRoot ? root : document.head; // Use ShadowRoot if available, otherwise fall back to document.head
20
21 // Create Emotion cache with the appropriate container
22 const emotionCache = createCache({ key: "mui", container });
23 setCache(emotionCache);
24 }
25 }, []);
26
27 // Show placeholder div while cache is being created
28 if (!cache) {
29 return <div ref={ref} />;
30 }
31
32 // Wrap children with Emotion's CacheProvider once cache is ready
33 return <CacheProvider value={cache}>{children}</CacheProvider>;
34};

Using the Shadow DOM provider

Rating.webflow.tsx
1import { declareComponent } from "@webflow/react";
2import { Rating as MuiRating } from "@mui/material";
3import { ShadowDomProvider } from "./ShadowDomProvider";
4
5// Wrap the MuiRating component in the ShadowDomProvider to ensure styles are injected into the Shadow DOM
6const Rating = () => {
7 return (
8 <ShadowDomProvider>
9 <MuiRating />
10 </ShadowDomProvider>
11 );
12};
13
14export default declareComponent(Rating, {
15 name: "Rating",
16 description: "A simple rating component",
17 group: "Forms",
18});

Learn about additional configuration options in the bundling and deployment guide.

Next steps