Skip to content

Commit

Permalink
inject initial styles to end of head, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Aug 3, 2022
1 parent d289a2b commit 6c86578
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/next/server/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,7 @@ export async function renderToHTMLOrFlight(
dataStream: serverComponentsInlinedTransformStream?.readable,
generateStaticHTML: generateStaticHTML || !hasConcurrentFeatures,
flushEffectHandler,
flushEffectsToHead: true,
initialStylesheets,
})
}
Expand Down
21 changes: 15 additions & 6 deletions packages/next/server/node-web-streams-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export function createFlushEffectStream(
}

export function createHeadInjectionTransformStream(
inject: string
inject: () => string
): TransformStream<Uint8Array, Uint8Array> {
let injected = false
return new TransformStream({
Expand All @@ -147,7 +147,7 @@ export function createHeadInjectionTransformStream(
if (!injected && (index = content.indexOf('</head')) !== -1) {
injected = true
const injectedContent =
content.slice(0, index) + inject + content.slice(index)
content.slice(0, index) + inject() + content.slice(index)
controller.enqueue(encodeText(injectedContent))
} else {
controller.enqueue(chunk)
Expand Down Expand Up @@ -175,12 +175,14 @@ export async function continueFromInitialStream(
dataStream,
generateStaticHTML,
flushEffectHandler,
flushEffectsToHead,
initialStylesheets,
}: {
suffix?: string
dataStream?: ReadableStream<Uint8Array>
generateStaticHTML: boolean
flushEffectHandler?: () => string
flushEffectsToHead: boolean
initialStylesheets?: string[]
}
): Promise<ReadableStream<Uint8Array>> {
Expand All @@ -193,15 +195,22 @@ export async function continueFromInitialStream(

const transforms: Array<TransformStream<Uint8Array, Uint8Array>> = [
createBufferedTransformStream(),
flushEffectHandler ? createFlushEffectStream(flushEffectHandler) : null,
flushEffectHandler && !flushEffectsToHead
? createFlushEffectStream(flushEffectHandler)
: null,
suffixUnclosed != null ? createDeferredSuffixStream(suffixUnclosed) : null,
dataStream ? createInlineDataStream(dataStream) : null,
suffixUnclosed != null ? createSuffixStream(closeTag) : null,
createHeadInjectionTransformStream(
(initialStylesheets || [])
createHeadInjectionTransformStream(() => {
const inlineStyleLinks = (initialStylesheets || [])
.map((href) => `<link rel="stylesheet" href="/_next/${href}">`)
.join('')
),
// TODO-APP: Inject flush effects to end of head in app layout rendering, to avoid
// hydration errors. Remove this once it's ready to be handled by react itself.
const flushEffectsContent =
flushEffectHandler && flushEffectsToHead ? flushEffectHandler() : ''
return inlineStyleLinks + flushEffectsContent
}),
].filter(nonNullable)

return transforms.reduce(
Expand Down
1 change: 1 addition & 0 deletions packages/next/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,7 @@ export async function renderToHTML(
dataStream: serverComponentsInlinedTransformStream?.readable,
generateStaticHTML,
flushEffectHandler,
flushEffectsToHead: false,
})
}

Expand Down
14 changes: 10 additions & 4 deletions test/e2e/app-dir/rsc-basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ describe('app dir - react server components', () => {
'next.config.js': new FileRef(path.join(appDir, 'next.config.js')),
},
dependencies: {
'styled-jsx': 'latest',
'styled-components': '6.0.0-alpha.5',
react: 'experimental',
'react-dom': 'experimental',
},
Expand Down Expand Up @@ -320,11 +322,15 @@ describe('app dir - react server components', () => {
expect(content).toContain('bar.server.js:')
})

it.skip('should SSR styled-jsx correctly', async () => {
const html = await renderViaHTTP(next.url, '/styled-jsx')
const styledJsxClass = getNodeBySelector(html, 'h1').attr('class')
it('should render initial styles of css-in-js in SSR correctly', async () => {
const html = await renderViaHTTP(next.url, '/css-in-js')
const head = getNodeBySelector(html, 'head').html()

expect(html).toContain(`h1.${styledJsxClass}{color:red}`)
// from styled-jsx
expect(head).toMatch(/{color:(\s*)purple;?}/)

// from styled-components
expect(head).toMatch(/{color:(\s*)blue;?}/)
})

it('should support streaming for flight response', async () => {
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/app-dir/rsc-basic/app/layout.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ export default function AppLayout({ children }) {
return (
<html>
<head>
{/* TODO-APP: title will cause hydration issue with style injection */}
{/* <title>RSC</title> */}
<title>RSC</title>
</head>
<body>
<RootStyleRegistry>{children}</RootStyleRegistry>
Expand Down

0 comments on commit 6c86578

Please sign in to comment.