sandpack icon indicating copy to clipboard operation
sandpack copied to clipboard

Next.js App Router: `createContext is not a function`

Open karlhorky opened this issue 1 year ago • 1 comments

Bug report

First of all, thanks so much for CodeSandbox and Sandpack, amazing set of software and ecosystem!

Packages affected

  • [ ] sandpack-client
  • [x] sandpack-react

Description of the problem

A createContext ... is not a function error appears when adding the <Sandpack /> component from @codesandbox/sandpack-react to a Next.js App Router app, without using an intermediate Client Component:

 Uncaught Error: (0 , react__WEBPACK_IMPORTED_MODULE_1__.createContext) is not a function
    at eval (webpack-internal:///(/rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]_ty42msw37v2yis2tc3yfoj3cpi/node_modules/@codesandbox/sandpack-react/dist/index.mjs:506:77)
    at (rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]_ty42msw37v2yis2tc3yfoj3cpi/node_modules/@codesandbox/sandpack-react/dist/index.mjs (/project/workspace/.next/server/vendor-chunks/@[email protected]_@[email protected][email protected]_ty42msw37v2yis2tc3yfoj3cpi.js:20:1)
    at __webpack_require__ (/project/workspace/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///(/rsc)/./app/page.tsx:7:85)
    at (rsc)/./app/page.tsx (/project/workspace/.next/server/app/page.js:141:1)
    at Function.__webpack_require__ (/project/workspace/.next/server/webpack-runtime.js:33:42)
    at async e9 (/project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:483832)
    at async tb (/project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:487554)
    at async tS (/project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:488115)
    at async tS (/project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:488246)
    at async tj (/project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:36:2138)
    at async (/project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:36:2793)
at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]_ty42msw37v2yis2tc3yfoj3cpi/node_modules/@codesandbox/sandpack-react/dist/index.mjs:506:77) @ 
at (rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]_ty42msw37v2yis2tc3yfoj3cpi/node_modules/@codesandbox/sandpack-react/dist/index.mjs (file:///project/workspace/.next/server/vendor-chunks/@[email protected]_@[email protected][email protected]_ty42msw37v2yis2tc3yfoj3cpi.js:20:1) @ 
at __webpack_require__ (file:///project/workspace/.next/server/webpack-runtime.js:33:42) @ 
at eval (webpack-internal:///(rsc)/./app/page.tsx:7:85) @ 
at (rsc)/./app/page.tsx (file:///project/workspace/.next/server/app/page.js:141:1) @ 
at Function.__webpack_require__ (file:///project/workspace/.next/server/webpack-runtime.js:33:42) @ 
at async e9 (file:///project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:483832) @ 
at async tb (file:///project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:487554) @ 
at async tS (file:///project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:488115) @ 
at async tS (file:///project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:488246) @ 
at async tj (file:///project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:36:2138) @ 
at async (file:///project/workspace/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:36:2793) @ 
[HMR] connected

What were you doing when the problem occurred?

Adding the <Sandpack /> component from @codesandbox/sandpack-react to a Next.js App Router app, without using an intermediate Client Component

I would argue that <Sandpack /> should work out of the box when imported into a Server Component. This will become a larger issue in future as more metaframeworks ship RSCs.

Regarding the docs, I'm aware that the Next.js (app dir) docs section exists, but these docs do not explicitly mention the Client Component requirements, and again, I would argue it would be better if it "just worked" out of the box, without having to consult docs after unusual errors.

What steps can we take to reproduce the problem?

  1. Create a new Next.js App Router app
  2. Import and use <Sandpack /> from @codesandbox/sandpack-react in app/page.tsx
  3. Observe the error

A reproduction is also contained in the sandbox below.

Link to sandbox: link (optional)

Screenshot:

Screenshot 2024-06-27 at 19 12 53

Cause / Suggestion

This is caused by the published .js and .mjs files in Sandpack not having 'use client', identifying them as Client Components eg. dist/index.mjs:

import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import * as React from 'react';
import { createContext, useContext, useState, useRef, useCallback, useEffect, createElement, forwardRef } from 'react';
import { createStitches } from '@stitches/core';
// ...

Adding 'use client' to the first line in this file resolves the issue.

Suggestion

Add 'use client' to top of all files using Client Component features

Your Environment

Software Name/Version
Sandpack-client version 2.14.4
Sandpack-react version
Browser Chrome 126.0.6478.127
Operating System macOS Sonoma 14.5 (23F79)

karlhorky avatar Jun 27 '24 17:06 karlhorky

Workaround

Use patch-package or pnpm patch to add 'use client' to the top of any file that you're importing from @codesandbox/sandpack-react - eg. node_modules/@codesandbox/sandpack-react/dist/index.mjs or node_modules/@codesandbox/sandpack-react/dist/index.js:

+'use client';
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import * as React from 'react';
import { createContext, useContext, useState, useRef, useCallback, useEffect, createElement, forwardRef } from 'react';
import { createStitches } from '@stitches/core';
import { dequal } from 'dequal';
// ...

karlhorky avatar Jun 27 '24 17:06 karlhorky

Hey! Thanks for reporting this issue. Unfortunately, Sandpack/Nodebox has limited support for Next.js applications at the moment, and we encourage you to use Next.js 13 if it works for you. I know this is frustrating, but due to limited resources, we are not actually working on solving open issues in Nodebox (including the next.js template).

We love Nodebox, our Node.js runtime, and we hope in the future, we can continue improving it, but for now, we can't make any promises about the timeline to solve this kind of issue.

danilowoz avatar Jul 01 '24 08:07 danilowoz

Ok, thanks for the answer.

To be clear about the scope, the fix is a 1-line, backwards-compatible change to your published files ('use client'; at the top of any file that uses Client Components features).

Also:

  • Next.js 13 is an old version now - Next.js 14 is the current version, and Next.js 15 is in RC, soon to be released
  • This won't only affect Next.js - this will affect all of the React metaframeworks that use RSC (others like Waku are already available, and some like React Router/Remix and RedwoodJS are working on compatibility)

karlhorky avatar Jul 01 '24 08:07 karlhorky

Oh sorry, I totally misread that (I need one more cup of coffee).

It makes sense to make the component client only, once Sandpack strongly relies on client APIs. I believe in the future we can introduce support to RSC where we could at least show the code-editor and its content, but for now your solution seems totally fine.

danilowoz avatar Jul 01 '24 08:07 danilowoz

Ok great, nice!

If it's not done by the CodeSandbox / Sandpack team, then maybe someone from the community will be able to take it over.

karlhorky avatar Jul 03 '24 09:07 karlhorky

@danilowoz why was this closed? I see that there is a new release @codesandbox/[email protected], but there is still no 'use client' at the top of dist/index.mjs:

import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import * as React from 'react';
import { createContext, useContext, useState, useRef, useCallback, useEffect, createElement, forwardRef } from 'react';
import { createStitches } from '@stitches/core';
// ...

karlhorky avatar Jul 06 '24 12:07 karlhorky

@danilowoz thanks for #1156, PR diff looks like it may be what is needed.

I'll wait for the next release to check - I guess it may be a patch release:

karlhorky avatar Jul 14 '24 09:07 karlhorky

Ah, for anyone following along here, this was released in a minor:

I confirm that the new version @codesandbox/[email protected] works in our Next.js app.

Thanks again @danilowoz !

karlhorky avatar Jul 26 '24 08:07 karlhorky