Skip to content

unstable_serialize doesn't work with NextJS edge runtime #3030

@william1616

Description

@william1616

Bug report

Description / Observed Behavior

When calling unstable_serialize from a server component that uses the NextJS edge runtime with an array or object key, the key is not serialized properly.

As an example, the code below logs 1~ to the console:

export const runtime = 'edge'

export default function Home() {
  const key = ['test']
  console.log(unstable_serialize(key))

  return "Hello"
}

Expected Behavior

I would expect the behavior in edge runtime to match the NodeJS runtime, with @"test", logged to the console (example code below)

export default function Home() {
  const key = ['test']
  console.log(unstable_serialize(key))

  return "Hello"
}

Additional Context

Debugging

I've done some digging, and the problem seems to originate from the stableHash function in the file: https://github.com/vercel/swr/blob/v2.2.5/src/_internal/utils/hash.ts.

  • Line 40 (if (constructor == Array) {) and Line 48 (if (constructor == OBJECT) {) don't return true for arrays/objects when using the edge runtime.

Further testing reveals that although key.constructor doesn't equal Array in the edge runtime, key instanceof Array returns true (same applies to objects).

A possible solution could be to change:

  • Line 40 to if (arg instanceof Array) {
  • Line 48 to if (arg instanceof OBJECT) {

This works in both the edge runtime and NodeJS runtime, but I'm unsure of the historical reasons for not using instanceof. Additionally, I'm not sure why arg.constructor doesn't equal Array or OBJECT in the edge runtime.

Package Versions

nextjs-swr-tests@0.1.0
├── @types/node@20.16.15
├── @types/react-dom@18.3.1
├── @types/react@18.3.12
├── eslint-config-next@14.2.16
├── eslint@8.57.1
├── next@14.2.16
├── react-dom@18.3.1
├── react@18.3.1
├── swr@2.2.5
└── typescript@5.6.3

Repro Steps / Code Example

I've built a test repository that demonstrates the issue. To reproduce:

  1. Clone the repo from https://github.com/william1616/nextjs-swr-edge-runtime-tests.
  2. Install the packages (npm i), and then run the development server (npm run dev).
  3. Open a browser and navigate to http://localhost:3000.
  4. Check the console output:
    • 1~ (the output of unstable_serialize).
    • true (key instanceof Array is true).
    • false (key.constructor == Array is false).
  5. In https://github.com/william1616/nextjs-swr-edge-runtime-tests/blob/main/src/app/page.tsx, comment out line 5 to change the runtime from edge to NodeJS.
  6. Refresh http://localhost:3000 in your browser.
  7. Check the console output:
    • @"test", (the output of unstable_serialize).
    • true (key instanceof Array is true).
    • true (key.constructor == Array is true).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions