mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
> [!NOTE] > This issue occurs only on: > - Pages Router > - Production > - Webpack Build ### Why? When client-side navigating from Page 1 to Page 2, where Page 1 **statically imports** CSS, whereas Page 2 **dynamically imports** CSS, the expected style is missing at Page 2. The root cause of the issue is the `mini-css-extract-plugin` (which handles Production CSS) skipped injecting the stylesheet since the `link` tag with the target `href` already existed. This is fine, but the expected stylesheet is missing as Next.js removes "server-rendered" stylesheets after the navigation.  ### How? Create a `dynamic-css-manifest` with the list of dynamic CSS files along with the `react-loadables-manifest`. Then, pass it to the internal `_document`'s `<Head>` component. During rendering the head, if the href of the target CSS is included in the dynamic CSS files list, do not add the `data-n-p` (attribute for server-rendered CSS) attribute. This is possible because we do not "unload" the dynamic stylesheets during the client navigation. Therefore, the result will be the same with removing the current stylesheet and then dynamically loading the same stylesheet. ### Testing Plan - Covers runtime `nodejs` and `edge` - `next/dynamic` - React `lazy` - dynamic `import()` Fixes #33286 Fixes #47655 Fixes #68328 Closes NDX-145 --------- Co-authored-by: Tobias Koppers <[email protected]> Co-authored-by: JJ Kasper <[email protected]>
28 lines
824 B
TypeScript
28 lines
824 B
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
|
|
describe.each(['edge', 'nodejs'])(
|
|
'dynamic-css-client-navigation dynamic import %s',
|
|
(runtime) => {
|
|
const { next } = nextTestSetup({
|
|
files: __dirname,
|
|
})
|
|
|
|
it(`should not remove style when navigating from static imported component to dynamic import at runtime ${runtime}`, async () => {
|
|
const browser = await next.browser(`/${runtime}`)
|
|
expect(
|
|
await browser
|
|
.elementByCss(`a[href="/${runtime}/dynamic-import"]`)
|
|
.click()
|
|
.waitForElementByCss('#red-button')
|
|
.text()
|
|
).toBe('Red Button')
|
|
|
|
const buttonBgColor = await browser.eval(
|
|
`window.getComputedStyle(document.querySelector('button')).backgroundColor`
|
|
)
|
|
|
|
expect(buttonBgColor).toBe('rgb(255, 0, 0)')
|
|
})
|
|
}
|
|
)
|