Any import from next-sanity prevents Next.js static builds (`output: 'export'`)
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
+1 this is definitely an issue. The workaround works at least.
I think when using next output: export and using next-sanity implementations, the same error appears
@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..
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
The VisualEditing is also bundled when not used, adding a lot to the bundle size.
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.
Thanks @dylansmith for the WA. I was able to fix this by replacing sanityFetch with the client.fetch and removing SanityLive.
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.
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.
Now that the PreviewKit is being retired (why??), next-sanity is going to become more important if not necessary.
@dylansmith Thanks for the workaround here! Hoping the Sanity team can fix this soon.
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 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.