Skip to content

Tailwind CSS Component Integration Protocol

Version: 1.0
Date: October 12, 2025
Status: MANDATORY FOR ALL COMPONENT WORK


This protocol defines the exact, tested procedure for integrating third-party Tailwind CSS components (Pagedone, Meraki UI, etc.) into our Nx monorepo. This procedure has been validated to work with both Storybook and production apps.

Critical Finding: The issue was never about Tailwind versions. Both Pagedone and Meraki UI work with any modern Tailwind CSS version because they use standard utility classes. The problem was monorepo configuration.


All versions must comply with the pre-October 2024 dependency policy defined in /README.md:

{
"tailwindcss": "3.4.10",
"postcss": "8.4.47",
"autoprefixer": "10.4.20"
}

Rationale: Tailwind v3.4.10 was the last stable release before October 2024, ensuring full GitHub Copilot compatibility.


  • Version: Any (uses standard Tailwind classes)
  • Installation: npm install pagedone (optional - we extract HTML/CSS directly)
  • Tailwind Requirement: Standard Tailwind CSS (no specific version)
  • Documentation: https://pagedone.io/docs/installation

Key Insight: Neither library requires special Tailwind versions. They use standard utility classes that work across Tailwind v2, v3, and v4.


cloudalt-frontend/
├── packages/
│ ├── ui-web/ # Generic components (cross-brand)
│ ├── ui-{brand}/ # Brand-specific components
│ ├── config/
│ │ └── tailwind-preset.js # Shared Tailwind configuration
│ └── storybook/ # Component development workspace
│ ├── .storybook/
│ │ ├── main.ts
│ │ └── preview.ts
│ ├── postcss.config.js
│ ├── tailwind.config.js
│ └── styles/tailwind.css
└── apps/
└── {brand}/{app}/web/
├── postcss.config.js
├── tailwind.config.js
└── styles/tailwind.css

  1. Navigate to component library (Pagedone or Meraki UI)
  2. Find desired component and copy the HTML
  3. DO NOT modify class names or structure yet
  4. Save HTML to a temporary file for reference

Location: packages/ui-web/src/components/{ComponentName}/

ComponentName.tsx
import React, { useState } from 'react';
export interface ComponentNameProps {
// Define props based on component requirements
}
export const ComponentName: React.FC<ComponentNameProps> = ({
// Props
}) => {
// Convert HTML to JSX
// Keep ALL Tailwind classes exactly as provided
return (
<section className="...">
{/* Component JSX */}
</section>
);
};
export default ComponentName;

Critical Rules:

  • ✅ Keep Tailwind classes exactly as provided by Pagedone/Meraki UI
  • ✅ Convert HTML attributes to JSX (classclassName, forhtmlFor)
  • ✅ Add TypeScript types for props
  • ❌ DO NOT modify or “improve” Tailwind classes
  • ❌ DO NOT add custom CSS

Export Component:

index.ts
export { ComponentName } from './ComponentName';
export type { ComponentNameProps } from './ComponentName';

Update Package Index:

packages/ui-web/src/index.ts
export { ComponentName } from './components/ComponentName';
export type { ComponentNameProps } from './components/ComponentName';

Location: packages/storybook/stories/{ComponentName}.stories.tsx

import type { Meta, StoryObj } from '@storybook/react';
import { ComponentName } from '@cloudalt-frontend/ui-web';
const meta: Meta<typeof ComponentName> = {
title: 'Components/ComponentName',
component: ComponentName,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof ComponentName>;
export const Default: Story = {
args: {
// Add default props
},
};
Terminal window
yarn storybook

Navigate to http://localhost:6006/ and verify:

  • ✅ Component renders correctly
  • ✅ All styles apply properly
  • ✅ Interactive elements work
  • ✅ Responsive design works
  • ✅ Dark mode works (if applicable)

If component doesn’t render correctly:

  1. Check browser console for errors
  2. Verify Tailwind config scans the correct paths
  3. Confirm component is exported from ui-web

Required Files for Each Web App:

// apps/{brand}/{app}/web/postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
// apps/{brand}/{app}/web/tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
presets: [require('../../../../packages/config/tailwind-preset.js')],
content: [
'./index.html',
'./src/**/*.{js,jsx,ts,tsx}',
'../../../../packages/ui-web/src/**/*.{js,jsx,ts,tsx}',
'../../../../packages/ui-{brand}/src/**/*.{js,jsx,ts,tsx}',
],
};

Critical: Content paths MUST include:

  • App’s own source files
  • packages/ui-web (generic components)
  • Brand-specific UI package
/* apps/{brand}/{app}/web/styles/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html, body {
margin: 0;
padding: 0;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
}
// apps/{brand}/{app}/web/src/main.tsx
import '../styles/tailwind.css';
// apps/{brand}/{app}/web/vite.config.ts
export default defineConfig(() => ({
// ... other config
css: {
postcss: './postcss.config.js',
},
// ... other config
}));
// apps/{brand}/{app}/web/src/app/app.tsx
import { ComponentName } from '@cloudalt-frontend/ui-web';
export function App() {
return (
<div>
<ComponentName {...props} />
</div>
);
}
Terminal window
yarn nx run {app}:serve

Navigate to http://localhost:4200/ and verify:

  • ✅ Component renders identically to Storybook
  • ✅ All styles apply
  • ✅ Responsive design works
  • ✅ No console errors

Problem: Component renders but has no styling

Section titled “Problem: Component renders but has no styling”

Root Cause: Tailwind not scanning the component’s source files.

Solution:

  1. Check tailwind.config.js content paths
  2. Ensure paths use correct relative paths (e.g., ../../../../packages/ui-web/src/**/*.{js,jsx,ts,tsx})
  3. Restart dev server after config changes

Problem: Component works in Storybook but not in app

Section titled “Problem: Component works in Storybook but not in app”

Root Cause: App’s Tailwind config doesn’t match Storybook’s.

Solution:

  1. Compare content arrays in both configs
  2. Ensure app scans all necessary package paths
  3. Verify PostCSS is configured correctly

Problem: Some Tailwind classes work, others don’t

Section titled “Problem: Some Tailwind classes work, others don’t”

Root Cause: Class name conflicts or purging issues.

Solution:

  1. Check if using v3 or v4 syntax (don’t mix)
  2. Verify no custom CSS overriding Tailwind
  3. Clear build cache: rm -rf node_modules/.vite

Root Cause: Attempting to use Tailwind v4 features with v3.

Solution:

  1. Stick to v3.4.10 per repository policy
  2. Avoid v4-specific syntax (@import "tailwindcss", @source)
  3. Use v3 syntax (@tailwind base, @tailwind components, @tailwind utilities)

If component uses images:

  1. Store in: packages/assets/{category}/{component-name}/
  2. Copy to app public folder: apps/{brand}/{app}/web/public/images/
  3. Reference in component: /images/{filename}

Components from Pagedone/Meraki often use CDN URLs - these work as-is.


Before considering integration complete:

  • Component renders in Storybook
  • All interactive features work in Storybook
  • Component renders identically in target app
  • Responsive design works (test mobile, tablet, desktop)
  • Dark mode works (if applicable)
  • No console errors or warnings
  • TypeScript types are correct
  • Component is exported from package index
  • Story is documented with controls
  • Assets are properly referenced

  1. Modifying Tailwind classes from original component
  2. Forgetting to add package to Tailwind content paths
  3. Using relative imports instead of package aliases
  4. Not restarting dev server after config changes
  5. Mixing Tailwind v3 and v4 syntax
  6. Installing incompatible Tailwind versions
  7. Not testing in both Storybook and app

Tool/LibraryRequired VersionRationale
Tailwind CSS3.4.10Last pre-Oct 2024 release
PostCSS8.4.47Compatible with Tailwind 3.4.10
Autoprefixer10.4.20Compatible with PostCSS 8.4.47
PagedoneAnyUses standard Tailwind classes
Meraki UILatestUses standard Tailwind classes
Storybook8.6.14Current repo version
React18.3.1Current repo version

If Tailwind setup is completely broken:

Terminal window
# 1. Remove all Tailwind-related packages
yarn remove tailwindcss postcss autoprefixer @tailwindcss/postcss @tailwindcss/vite @tailwindcss/cli
# 2. Reinstall correct versions
yarn add -D tailwindcss@3.4.10 postcss@8.4.47 autoprefixer@10.4.20
# 3. Verify all configs use v3 syntax
# Check: @tailwind directives (not @import "tailwindcss")
# Check: tailwind.config.js exists (not using @source)
# 4. Clear caches
rm -rf node_modules/.vite
rm -rf dist
# 5. Restart everything
yarn nx reset
yarn install

Review Frequency: Quarterly or when major Tailwind versions release

Update Procedure:

  1. Check if new Tailwind version is pre-October 2024 compatible
  2. Test in isolated branch
  3. Verify all existing components still work
  4. Update this document if procedures change


Last Updated: October 12, 2025
Next Review: January 2026
Protocol Owner: Development Team