next-sanity icon indicating copy to clipboard operation
next-sanity copied to clipboard

Any import from next-sanity prevents Next.js static builds (`output: 'export'`)

Open dylansmith opened this issue 1 year ago • 13 comments

Describe the bug

We recently tried to build our Next.js (14.2.14) project using static exports via the output: 'export' config. However, the build kept failing with the error message:

> Server Actions are not supported with static export.

As the message says, you cannot render an app with Server Actions as a static site, but we were not using any server actions in our code. After hours of trying to figure out why Next was behaving this way, I isolated the issue to imports from next-sanity like these:

import { defineQuery } from 'next-sanity';

It appears as though the module packages/next-sanity/src/visual-editing/server-actions/index.ts is the culprit here. Possibly there is a chain of imports in place that whenever you import from next-sanity this module is resolved as well. In our case (as will be for many others using Sanity) our Next.js pages will run a query against Sanity on every page request so if the import from next-sanity is in this codepath then all pages will not be able to be statically generated.

I was able to workaround this issue by changing the following imports:

// import { defineQuery } from 'next-sanity';
import { defineQuery } from 'groq';

// import { groq } from 'next-sanity';
import groq from 'groq'`;

// import { createClient } from 'next-sanity';
import { createClient, SanityClient } from '@sanity/client';

To Reproduce

Steps to reproduce the behavior:

Add an import from next-sanity to any Next.js page or a module that is imported into a page, e.g.

import { defineQuery } from 'next-sanity';
import { groq } from 'next-sanity';

Expected behavior

Imports from next-sanity that are unrelated to visual editing should not break static builds in Next.js.

Which versions of Sanity are you using?

@sanity/cli (global)                   3.59.0 (latest: 3.63.0)
@sanity/document-internationalization   3.1.0 (up to date)
@sanity/image-url                       1.0.2 (latest: 1.1.0)
@sanity/vision                         3.59.0 (latest: 3.63.0)
sanity                                 3.59.0 (latest: 3.63.0)

What operating system are you using?

MacOS 13.4 (22F66)

Which versions of Node.js / npm are you running?

10.8.2
v22.6.0

Additional context

Add any other context about the problem here.

Security issue?

N/A

dylansmith avatar Nov 08 '24 17:11 dylansmith

+1 this is definitely an issue. The workaround works at least.

giangiuliani avatar Nov 27 '24 08:11 giangiuliani

I think when using next output: export and using next-sanity implementations, the same error appears

junghyeonsu avatar Dec 08 '24 06:12 junghyeonsu

@dylansmith How have you solved sanityFetch ?

My live.ts is

import { defineLive } from "next-sanity";
import { client } from "./client";
import { token } from "./token";

export const { sanityFetch, SanityLive } = defineLive({
  client: client.withConfig({ apiVersion: "vX" }),
  browserToken: token,
  serverToken: token,
});

I tried to change import { defineLive } from "next-sanity"; by import { defineLive } from "@sanity/next-loader"; but I still get Server Actions are not supported with static export..

cbou avatar Dec 22 '24 21:12 cbou

I’m seeing this same issue.

import { createClient } from "next-sanity"

export default async function Home() {
  const res = await fetch("https://api.vercel.app/blog")
  const page = await res.json()
  // ^ this fetch works, just a "sanity" check to confirm that async fetches can build normally.

  const client = createClient({
    projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
    dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
    apiVersion: process.env.NEXT_PUBLIC_SANITY_API_VERSION,
    useCdn: true,
  })
  // ^ this breaks the build. If commented out, build is fine.
  return <p>{page.length} results</p>
}

@dylansmith’s workaround does appear to work (Next v15), so I’ll pursue that in my actual app. THANK YOU

EricWVGG avatar Dec 30 '24 19:12 EricWVGG

The VisualEditing is also bundled when not used, adding a lot to the bundle size.

eivindml avatar Jan 06 '25 15:01 eivindml

I'm pretty sure the problem is with this file: https://github.com/sanity-io/visual-editing/blob/main/packages/next-loader/src/server-actions/index.ts

Not sure how that could be conditional to static exports though.

george-activetheory avatar Jan 31 '25 14:01 george-activetheory

Thanks @dylansmith for the WA. I was able to fix this by replacing sanityFetch with the client.fetch and removing SanityLive.

LynxUA avatar Feb 16 '25 16:02 LynxUA

Adding to this issue, how can it not be important, especially with VisualEditing being bundled when it's not used.

@dylansmith you seem to be correct by the culprit. That server function is imported in VisualEditing client component (Line 9) that is directly exported from the next-sanity package.

pauliusef avatar Apr 06 '25 05:04 pauliusef

For anyone still having issue even after applying the workaround suggested.

You have to make sure to never import anything directly from 'next-sanity'. It's okay to import from a subpath like 'next-sanity/image' or 'next-sanity/studio'. I had PortableText related import from 'next-sanity' that were causing issues. You should install the original dependencies like '@portabletext/react' and import what you need from there directly.

jazsouf avatar Apr 17 '25 17:04 jazsouf

Now that the PreviewKit is being retired (why??), next-sanity is going to become more important if not necessary.

EricWVGG avatar Apr 27 '25 00:04 EricWVGG

@dylansmith Thanks for the workaround here! Hoping the Sanity team can fix this soon.

kupe517 avatar May 29 '25 23:05 kupe517

First time using Sanity with Next.js and having this issue also, for me the two imports that are causing it were:

import { createClient } from 'next-sanity';
import { PortableText } from 'next-sanity';

Fixed by replacing them with:

import { createClient } from '@sanity/client';
import { PortableText } from '@portabletext/react';

manfromanotherland avatar Jun 10 '25 11:06 manfromanotherland

@manfromanotherland same here, they should probably not re-export anything from next-sanity so that IDE auto-import avoids choosing the module that cannot tree-shake everything else away.

silvertech-daniel avatar Jun 10 '25 13:06 silvertech-daniel