Skip to content

Comments

Fix: css in next/dynamic component in edge runtime (#64382)#1

Open
MitchLewis930 wants to merge 1 commit intopr_031_beforefrom
pr_031_after
Open

Fix: css in next/dynamic component in edge runtime (#64382)#1
MitchLewis930 wants to merge 1 commit intopr_031_beforefrom
pr_031_after

Conversation

@MitchLewis930
Copy link

@MitchLewis930 MitchLewis930 commented Jan 30, 2026

User description

PR_031


PR Type

Bug fix


Description

  • Wrap async local storage for edge runtime request handlers

  • Fix CSS imports in next/dynamic components on edge runtime

  • Update PreloadCss to pass context identifier to getExpectedRequestStore

  • Add test coverage for edge runtime CSS loading


Diagram Walkthrough

flowchart LR
  A["Edge Runtime Request"] -->|Previously Unwrapped| B["Handler Execution"]
  B -->|Missing ALS Context| C["CSS Preload Fails"]
  A -->|Now Wrapped| D["RequestAsyncStorageWrapper"]
  D -->|ALS Context Available| E["Handler Execution"]
  E -->|CSS Preload Works| F["Correct Styles Applied"]
Loading

File Walkthrough

Relevant files
Bug fix
adapter.ts
Wrap edge runtime handlers with async storage                       

packages/next/src/server/web/adapter.ts

  • Wrap all edge runtime request handlers with RequestAsyncStorageWrapper
  • Previously only wrapped handlers with preview mode, now wraps all
    handlers
  • Ensures async local storage context is available for CSS preloading
+7/-1     
preload-css.tsx
Pass context identifier to request store getter                   

packages/next/src/shared/lib/lazy-dynamic/preload-css.tsx

  • Update getExpectedRequestStore call to pass context identifier
    'next/dynamic css'
  • Improve type annotation for the imported function
  • Ensures proper request store retrieval in dynamic CSS preloading
+4/-4     
Tests
page.js
Add edge runtime test page                                                             

test/e2e/app-dir/dynamic-css/app/ssr/edge/page.js

  • Create new test page that re-exports parent page with edge runtime
  • Enables testing of CSS loading behavior in edge runtime environment
+3/-0     
index.test.ts
Add edge runtime CSS loading test                                               

test/e2e/app-dir/dynamic-css/index.test.ts

  • Add test case for CSS loading in edge runtime
  • Verify correct styles are applied and unrelated CSS is not loaded
  • Validates fix for dynamic CSS in edge runtime
+17/-0   

### What

Wrap async local storage for all edge runtime routes in adapter 

Basically fixed the case reported in [this
tweet](https://x.com/keegandonley/status/1778538456458854880)

### Why

We're relying on the ALS for dynamic css preloading but we didn't wrap
the ALS for request handlers for edge. So if you have CSS imports in
`next/dynamic` in edge runtime it would break.

Closes NEXT-3085
@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Refactor tests to reduce duplication

Refactor the new test case and an existing one to use it.each to reduce code
duplication and improve maintainability.

test/e2e/app-dir/dynamic-css/index.test.ts [34-49]

-it('should only apply corresponding css for page loaded in edge runtime', async () => {
-  const browser = await next.browser('/ssr/edge')
-  await retry(async () => {
-    expect(
-      await browser.eval(
-        `window.getComputedStyle(document.querySelector('.text')).color`
-      )
-    ).toBe('rgb(255, 0, 0)')
-    // Default border width, which is not effected by bar.css that is not loaded in /ssr
-    expect(
-      await browser.eval(
-        `window.getComputedStyle(document.querySelector('.text')).borderWidth`
-      )
-    ).toBe('0px')
-  })
-})
+it.each([
+  { runtime: 'node', path: '/ssr' },
+  { runtime: 'edge', path: '/ssr/edge' },
+])(
+  'should only apply corresponding css for page loaded in $runtime runtime',
+  async ({ path }) => {
+    const browser = await next.browser(path)
+    await retry(async () => {
+      expect(
+        await browser.eval(
+          `window.getComputedStyle(document.querySelector('.text')).color`
+        )
+      ).toBe('rgb(255, 0, 0)')
+      // Default border width, which is not effected by bar.css that is not loaded in /ssr
+      expect(
+        await browser.eval(
+          `window.getComputedStyle(document.querySelector('.text')).borderWidth`
+        )
+      ).toBe('0px')
+    })
+  }
+)
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: This is a good suggestion for improving test code quality by refactoring duplicated test logic using it.each, which enhances maintainability.

Low
  • More

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants