shipyard uses Tailwind CSS 4 with DaisyUI for styling. This guide explains how to configure Tailwind CSS to work correctly with shipyard components.
Create src/styles/app.css:
/* Tailwind CSS 4 setup */
@import "tailwindcss";
/* Import shipyard packages - includes styles and @source directives */
@import "@levino/shipyard-base";
@import "@levino/shipyard-blog";
@import "@levino/shipyard-docs";
@plugin "daisyui";
@plugin "@tailwindcss/typography";
Update astro.config.mjs:
import shipyard from '@levino/shipyard-base'
import shipyardDocs from '@levino/shipyard-docs'
import shipyardBlog from '@levino/shipyard-blog'
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'astro/config'
import appCss from './src/styles/app.css?url'
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
integrations: [
shipyard({
css: appCss,
brand: 'My Site',
title: 'My Awesome Site',
navigation: {
docs: { label: 'Docs', href: '/docs' },
blog: { label: 'Blog', href: '/blog' },
},
}),
shipyardDocs(),
shipyardBlog(),
],
})
Install dependencies:
npm install tailwindcss @tailwindcss/vite daisyui @tailwindcss/typography
That’s it! The shipyard packages include their own @source directives, so Tailwind automatically detects all component classes.
Each shipyard package exports CSS via conditional exports. When imported in CSS with @import, it resolves to a CSS file that contains:
@apply directivesWhen you import @import "@levino/shipyard-base", Tailwind CSS 4:
@source directives to scan the package’s source filesThis means you don’t need to manually configure paths or worry about monorepo vs regular install differences.
| Directive | Purpose |
|---|---|
@import "tailwindcss" | Initializes Tailwind CSS |
@import "@levino/shipyard-*" | Imports shipyard styles and @source directives |
@plugin "daisyui" | Enables DaisyUI component classes |
@plugin "@tailwindcss/typography" | Enables prose styling for markdown content |
?url Import?The ?url suffix in import appCss from './src/styles/app.css?url' tells Vite to resolve the file path at build time. This allows shipyard to include your CSS in the correct processing order.
@tailwindcss/vite?Tailwind CSS 4 uses a Vite plugin (@tailwindcss/vite) instead of the older @astrojs/tailwind integration. This provides better performance and native Vite integration.
If components appear unstyled:
@import "tailwindcss" must come firstcss: appCss to the shipyard integrationThis error means Tailwind isn’t initialized when processing a CSS file. Ensure your app.css has @import "tailwindcss" as the first import.
If you see errors after upgrading, try:
node_modules and reinstallrm -rf dist .astroIf you’re migrating from Tailwind CSS 3:
tailwind.config.mjs - Configuration now lives in CSS@astrojs/tailwind - No longer needed@tailwindcss/vite - The new Vite pluginsrc/styles/app.css - With the setup shown aboveastro.config.mjs - Add Vite plugin and import CSS with ?url// astro.config.mjs
import tailwind from '@astrojs/tailwind'
export default defineConfig({
integrations: [
tailwind({ applyBaseStyles: false }),
shipyard({ /* ... */ }),
],
})
// tailwind.config.mjs
export default {
content: [
'./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx}',
'node_modules/@levino/shipyard-*/**/*.{astro,js,ts}',
],
plugins: [typography, daisyui],
}
// astro.config.mjs
import tailwindcss from '@tailwindcss/vite'
import appCss from './src/styles/app.css?url'
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
integrations: [
shipyard({
css: appCss,
/* ... */
}),
],
})
/* src/styles/app.css */
@import "tailwindcss";
@import "@levino/shipyard-base";
@import "@levino/shipyard-blog";
@import "@levino/shipyard-docs";
@plugin "daisyui";
@plugin "@tailwindcss/typography";