next-sanity
next-sanity copied to clipboard
v3 ready version of code-input causing schema errors
I've been trying a few different ways of getting this to cooperate, but I keep hitting schema errors in Sanity.
// sanity.config.ts
import dynamic from "next/dynamic"
import { createConfig, Plugin } from "sanity"
import { deskTool } from "sanity/desk"
import structure from "./deskStructure"
import types from "./schemas"
const codeInput = () =>
dynamic<Plugin<void>>(
() =>
import("@sanity/code-input").then(
(mod) => mod.default.codeInput
) as Promise<any>,
{ ssr: false }
)
const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!
const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET!
const config = createConfig({
name: "default",
title: "strangelove-ventures",
projectId,
dataset,
plugins: [deskTool({ structure }), codeInput()],
schema: {
types,
},
basePath: "/studio",
})
export default config
I'm having to use next/dynamic
because when I pass the codeInput()
function into the config using the usual ES6 import pattern, I get a 'window undefined' error.
I'm getting the schema error when I attempt to add the code
type to my blockContent
schema:
// blockContent.ts
const blockContent = {
title: "Block Content",
name: "blockContent",
type: "array",
of: [
{
title: "Block",
type: "block",
styles: [
{ title: "Normal", value: "normal" },
{ title: "H1", value: "h1" },
{ title: "H2", value: "h2" },
{ title: "H3", value: "h3" },
{ title: "H4", value: "h4" },
{ title: "Quote", value: "blockquote" },
],
marks: {
decorators: [
{ title: "Strong", value: "strong" },
{ title: "Emphasis", value: "em" },
],
annotations: [
{
title: "URL",
name: "link",
type: "object",
fields: [
{
title: "URL",
name: "href",
type: "url",
},
],
},
],
},
},
{
type: "image",
options: { hotspot: true },
},
{
type: "code",
},
],
}
export default blockContent
Relevant deps from my package.json
:
{
"dependencies": {
"@portabletext/react": "1.0.6",
"@sanity/code-input": "^3.0.0-v3-studio.2",
"@sanity/image-url": "^1.0.1",
"@sanity/next-studio-layout": "^2.0.0-v3-studio.8",
"next": "12.2.4",
"next-sanity": "0.5.2",
"react": "18.1.0",
"react-dom": "18.1.0",
},
"devDependencies": {
"@types/node": "17.0.41",
"@types/styled-components": "^5.1.25",
"eslint": "8.17.0",
"eslint-config-next": "12.1.6",
"prettier": "2.6.2",
"sanity": "^3.0.0-dev-preview.12",
"sanity-codegen": "^0.9.8",
"styled-components": "^5.3.5",
"typescript": "4.7.3"
}
}
cc @snorrees
For those running into similar issues, here was the solve:
// sanity.config.ts
import { codeInput } from "@sanity/code-input"
import { createConfig } from "sanity"
import { deskTool } from "sanity/desk"
import structure from "./deskStructure"
import types from "./schemas"
const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!
const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET!
const config = createConfig({
name: "default",
title: "whatever",
projectId,
dataset,
plugins: [deskTool({ structure }), codeInput()],
schema: {
types,
},
basePath: "/studio",
})
export default config
// pages/studio/[[...index]].tsx
import { StudioPageLayoutProps } from "@sanity/next-studio-layout"
import { NextPage } from "next"
import dynamic from "next/dynamic"
import React from "react"
import config from "studio/sanity.config"
const StudioPageLayout = dynamic<StudioPageLayoutProps>(
() =>
import("@sanity/next-studio-layout").then(
(mod) => mod.StudioPageLayout
),
{ ssr: false }
)
const Sanity: NextPage = () => <StudioPageLayout config={config} />
export default Sanity
I swear I had tried this pattern before, but you need to dynamically import the <StudioPageLayout />
, not the code-input plugin. Hope this helps!
To the best of my knowledge, this is happening because of the ace editor the code-input plugin is built on top of. I only had to resort to this pattern once the plugin was added.
@xanderjl hey, thanks for reporting! This is definitely a problem with the ace dependency: it interacts with the window object directly without any checks. This fails in a node environment, like you experienced.
We just released a new version of v3 code input. In it, we lazy load any ace-editor related code, so that it should render a placeholder on the server. With it, you no longer should have to your dynamic workaround for next-studio-layout 🤞
We just released a new version of v3 code input
I noticed and took it for a spin! I'm still hitting an SSR error in v4 and I think I may have found the culprit. PreviewCode.tsx
was still importing ReactAce
from the package directly. I've cloned the repo and am testing the lazy loading/suspense wrapper pattern locally 👀
Hmm that didn't seem to fix it either. At a bit of a loss 😅
Never mind I fixed it! Will open a PR shortly
So much for me writing unit tests to reproduce when I didnt test it a SSR stack 🙈
Turns out I don't have access to push up my branch, which makes sense 😅
Is there an article outlining how to contribute to the sanity org repos?
I think you would have to make a fork. But from what you are saying, simply adding the hook to the preview comp should fix it right? I'll get on that tomorrow!
@xanderjl just released a new version of code-input that also makes the ace-code async in the preview component.
Let me know if it works out for you now; I just tested this in a regular studio deploy atm.
@snorrees just bumped to the latest version and it's working as intended! Thanks for addressing this so quickly 😁
Thats great to hear! Thanks for testing it!
Thanks for reporting @xanderjl !