diff --git a/integrations/vite/svelte.test.ts b/integrations/vite/svelte.test.ts
new file mode 100644
index 000000000000..5e3336b70792
--- /dev/null
+++ b/integrations/vite/svelte.test.ts
@@ -0,0 +1,76 @@
+import { expect } from 'vitest'
+import { candidate, html, json, test, ts } from '../utils'
+
+test(
+ 'production build',
+ {
+ fs: {
+ 'package.json': json`
+ {
+ "type": "module",
+ "dependencies": {
+ "svelte": "^4.2.18",
+ "tailwindcss": "workspace:^"
+ },
+ "devDependencies": {
+ "@sveltejs/vite-plugin-svelte": "^3.1.1",
+ "@tailwindcss/vite": "workspace:^",
+ "vite": "^5.3.5"
+ }
+ }
+ `,
+ 'vite.config.ts': ts`
+ import { defineConfig } from 'vite'
+ import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte'
+ import tailwindcss from '@tailwindcss/vite'
+
+ export default defineConfig({
+ plugins: [
+ svelte({
+ preprocess: [vitePreprocess()],
+ }),
+ tailwindcss(),
+ ],
+ })
+ `,
+ 'index.html': html`
+
+
+
+
+
+
+
+ `,
+ 'src/main.ts': ts`
+ import App from './App.svelte'
+ const app = new App({
+ target: document.body,
+ })
+ `,
+ 'src/App.svelte': html`
+
+
+ Hello {name}!
+
+
+ `,
+ },
+ },
+ async ({ fs, exec }) => {
+ await exec('pnpm vite build')
+
+ let files = await fs.glob('dist/**/*.css')
+ expect(files).toHaveLength(1)
+
+ await fs.expectFileToContain(files[0][0], [candidate`underline`, candidate`foo`])
+ },
+)
diff --git a/packages/@tailwindcss-vite/package.json b/packages/@tailwindcss-vite/package.json
index acbf1a1525d1..4914638d759b 100644
--- a/packages/@tailwindcss-vite/package.json
+++ b/packages/@tailwindcss-vite/package.json
@@ -31,12 +31,13 @@
"@tailwindcss/oxide": "workspace:^",
"lightningcss": "^1.25.1",
"postcss-load-config": "^6.0.1",
+ "svelte-preprocess": "^6.0.2",
"tailwindcss": "workspace:^"
},
"devDependencies": {
"@types/node": "catalog:",
- "vite": "catalog:",
- "internal-postcss-fix-relative-paths": "workspace:^"
+ "internal-postcss-fix-relative-paths": "workspace:^",
+ "vite": "catalog:"
},
"peerDependencies": {
"vite": "^5.2.0"
diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts
index e0bd810c08ef..f3504f95e169 100644
--- a/packages/@tailwindcss-vite/src/index.ts
+++ b/packages/@tailwindcss-vite/src/index.ts
@@ -3,6 +3,7 @@ import fixRelativePathsPlugin, { normalizePath } from 'internal-postcss-fix-rela
import { Features, transform } from 'lightningcss'
import path from 'path'
import postcssrc from 'postcss-load-config'
+import { sveltePreprocess } from 'svelte-preprocess'
import { compile } from 'tailwindcss'
import type { Plugin, ResolvedConfig, Rollup, Update, ViteDevServer } from 'vite'
@@ -173,6 +174,7 @@ export default function tailwindcss(): Plugin[] {
}
return [
+ svelteProcessor(),
{
// Step 1: Scan source files for candidates
name: '@tailwindcss/vite:scan',
@@ -347,7 +349,11 @@ function getExtension(id: string) {
function isTailwindCssFile(id: string, src: string) {
if (id.includes('/.vite/')) return
- return getExtension(id) === 'css' && src.includes('@tailwind')
+ const extension = getExtension(id)
+ const isTailwind =
+ (extension === 'css' && src.includes('@tailwind')) ||
+ (extension === 'svelte' && id.endsWith('&lang.css'))
+ return isTailwind
}
function optimizeCss(
@@ -373,3 +379,43 @@ function optimizeCss(
errorRecovery: true,
}).code.toString()
}
+
+// Register a plugin that can hook into the Svelte preprocessor if svelte is
+// enabled. This allows us to transform CSS in `