Skip to content

Commit 4fd1b65

Browse files
hi-ogawaclaude
andcommitted
fix(rsc): exclude CSS imports with special queries from collection
CSS imports with special queries (?url, ?inline, ?raw) should not be collected for server-side rendering as they return strings rather than applying styles. This fix adds a hasSpecialCssQuery() helper function to detect and exclude these imports from the collectCss function, preventing unexpected behavior while ensuring normal CSS imports continue to work correctly. - Add hasSpecialCssQuery() helper to detect ?url, ?inline, ?raw queries - Modify collectCss() to exclude CSS imports with special queries - Add comprehensive e2e tests for both server and client components - Test all query patterns with separate CSS files to ensure proper handling Fixes #571 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent df6a38e commit 4fd1b65

File tree

13 files changed

+182
-1
lines changed

13 files changed

+182
-1
lines changed

packages/plugin-rsc/e2e/basic.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,4 +1023,78 @@ function defineTest(f: Fixture) {
10231023
'test-browser-only: loading...',
10241024
)
10251025
})
1026+
1027+
test('css queries @js', async ({ page }) => {
1028+
await page.goto(f.url())
1029+
await waitForHydration(page)
1030+
await testCssQueries(page)
1031+
})
1032+
1033+
testNoJs('css queries @nojs', async ({ page }) => {
1034+
await page.goto(f.url())
1035+
await testCssQueries(page)
1036+
})
1037+
1038+
async function testCssQueries(page: Page) {
1039+
// Test that CSS with special queries (?url, ?inline, ?raw) don't break the page
1040+
// and that normal CSS imports still work for both server and client components
1041+
1042+
// Server component tests
1043+
await expect(
1044+
page.getByTestId('test-css-queries-server-normal'),
1045+
).toBeVisible()
1046+
1047+
// Client component tests
1048+
await expect(
1049+
page.getByTestId('test-css-queries-client-normal'),
1050+
).toBeVisible()
1051+
1052+
// Test that normal CSS imports are applied correctly to server component
1053+
await expect(page.locator('.test-css-query-server-normal')).toHaveCSS(
1054+
'background-color',
1055+
'rgb(255, 0, 0)',
1056+
)
1057+
await expect(page.locator('.test-css-query-server-normal')).toHaveCSS(
1058+
'color',
1059+
'rgb(0, 255, 0)',
1060+
)
1061+
1062+
// Test that normal CSS imports are applied correctly to client component
1063+
await expect(page.locator('.test-css-query-client-normal')).toHaveCSS(
1064+
'background-color',
1065+
'rgb(0, 0, 255)',
1066+
)
1067+
await expect(page.locator('.test-css-query-client-normal')).toHaveCSS(
1068+
'color',
1069+
'rgb(255, 255, 0)',
1070+
)
1071+
1072+
// Verify that URL query returns a string URL for server component (with filename pattern)
1073+
const serverUrlText = await page
1074+
.getByTestId('test-css-queries-server-url')
1075+
.textContent()
1076+
expect(serverUrlText).toMatch(/CSS URL \(server\): .*server-url.*\.css/)
1077+
1078+
// Verify that URL query returns a string URL for client component (with filename pattern)
1079+
const clientUrlText = await page
1080+
.getByTestId('test-css-queries-client-url')
1081+
.textContent()
1082+
expect(clientUrlText).toMatch(/CSS URL \(client\): .*client-url.*\.css/)
1083+
1084+
// Verify that inline and raw queries return strings for server component (should not be collected for SSR)
1085+
await expect(
1086+
page.getByTestId('test-css-queries-server-inline'),
1087+
).toContainText('CSS Inline (server): string')
1088+
await expect(page.getByTestId('test-css-queries-server-raw')).toContainText(
1089+
'CSS Raw (server): string',
1090+
)
1091+
1092+
// Verify that inline and raw queries return strings for client component (should not be collected for SSR)
1093+
await expect(
1094+
page.getByTestId('test-css-queries-client-inline'),
1095+
).toContainText('CSS Inline (client): string')
1096+
await expect(page.getByTestId('test-css-queries-client-raw')).toContainText(
1097+
'CSS Raw (client): string',
1098+
)
1099+
}
10261100
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.test-css-query-client-inline {
2+
padding: 8px;
3+
margin: 4px;
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.test-css-query-client-raw {
2+
font-weight: bold;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.test-css-query-client-url {
2+
border: 2px solid rgb(0, 0, 255);
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.test-css-query-client-normal {
2+
background-color: rgb(0, 0, 255);
3+
color: rgb(255, 255, 0);
4+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use client'
2+
3+
// Test CSS imports with special queries (?url, ?inline, ?raw) in client components
4+
// These should not be collected for server-side rendering
5+
import cssUrl from './client-url.css?url'
6+
import cssInline from './client-inline.css?inline'
7+
import cssRaw from './client-raw.css?raw'
8+
import './client.css' // Normal import should still work
9+
10+
export default function CssQueriesClientTest() {
11+
return (
12+
<div className="test-css-query-client-normal">
13+
<div data-testid="test-css-queries-client-url">
14+
CSS URL (client): {cssUrl}
15+
</div>
16+
<div
17+
data-testid="test-css-queries-client-inline"
18+
style={{ display: 'none' }}
19+
>
20+
CSS Inline (client):{' '}
21+
{typeof cssInline === 'string' ? 'string' : 'other'}
22+
</div>
23+
<div
24+
data-testid="test-css-queries-client-raw"
25+
style={{ display: 'none' }}
26+
>
27+
CSS Raw (client): {typeof cssRaw === 'string' ? 'string' : 'other'}
28+
</div>
29+
<div data-testid="test-css-queries-client-normal">
30+
Normal CSS import works (client)
31+
</div>
32+
</div>
33+
)
34+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.test-css-query-server-inline {
2+
padding: 4px;
3+
margin: 2px;
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.test-css-query-server-raw {
2+
text-decoration: underline;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.test-css-query-server-url {
2+
border: 2px solid rgb(255, 0, 0);
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.test-css-query-server-normal {
2+
background-color: rgb(255, 0, 0);
3+
color: rgb(0, 255, 0);
4+
}

0 commit comments

Comments
 (0)