Sanity.io is the platform for structured content. With Sanity.io you can use the open-source, single page application to manage your text, images, and other media with APIs. More! You can also use it to quickly set up an editing environment that you can customize.
Want to try Sanity.io with Next.js? This blog starter uses Next.js and Sanity which generates both the front-end and content editor so that you can jump immediately into action. The Sanity editor is React (with Typescript) which you can access by adding /studio to the url. It comes with real-time collaboration and instant "as-you-type" previews. Further down, you'll be shown how to configure ISR (incremental static rebuilding) for performant sites that can rebuild instantly.
If using the integration isn't an option. Or maybe you want to work locally first and deploy to Vercel later. Whatever the reason this guide shows you how to setup manually.
To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and import to Vercel. Important: When you import your project on Vercel, make sure to click on Environment Variables and set them to match your .env.local file. After it's deployed link your local code to the Vercel project:
npx vercel link
Step 3. Run Next.js locally in development mode
npm install && npm run dev
yarn install && yarn dev
When working locally you can make changes to your blog and studio, and your changes are applied live using hot reloading.
I'm using the api/revalidate to update content. But each time it updates, it returns one step old data. Not fresh.
I'm tried using bothuseCdn: true & false, but same result. Here, the webhook fires immediately after publishing, but apicdn takes upto 60 sec to update the content. Thus Next.js getting old data each time.
See below video.
Video transcription:
Starts next production builds
change “first post” to “Our first post”
Simulate “webhook” requests
Data do not change
[next attempt]
change “Our first post” to “Next first post”
Data change to Stale “Our First post” this time
but new data is “Next First Post” (edited)
~~When running locally (next dev) the post pages throw this error:~~
Error: Dynamic server usage: previewData
previewData blockers worked around, revisit in https://github.com/sanity-io/nextjs-blog-cms-sanity-v3/issues/95 once Next 13 is shipping an updated previewData() mechanic.
I tried using the shared config link for the revalidate webhook and ran into an internal server error until removing the dash from the webhook name. Not sure if sanity is suppose to allow dashes in webhook names, but may want to remove the dash in the config url (eg. name=On+demand+Revalidation).
To initiate a new Studio without installing the CLI globally:
npx create-sanity@latest
To upgrade a v3 Studio:
npm install sanity@latest
🐛 Notable bugfixes
Fixed a regression with release 3.1.0 where a custom style in the portable text input would not fallback to be rendered as the normal style when a rendering-component for that style was not defined.
To initiate a new Studio without installing the CLI globally:
npx create-sanity@latest
To upgrade a v3 Studio:
npm install sanity@latest
✨ Highlights
Improved customization and TypeScript support for the Portable Text Input and schemas
Improved support for custom rendering of the content in the Portable Text input via .components.block, component.inlineBlock and .components.annotation render callbacks for object-like schema types, references and type aliases.
While this has been possible previously by modifying the block schema locally, these customizations can now also be put directly on the various content types themselves, to be shared between different Portable Text inputs using them. For example you can now customize how an author reference would appear in various Portable Text contexts on the author schema itself.
Also text specific schema properties like decorators, styles and lists for the block type itself have slighly changed their configuration in order to better align with the rest of the studio. More info: Changes in block schema customization properties.
If you previously did customization of the editor using your own render callbacks or icons through the .blockEditor property in the block schema, you will get a deprecation warning, but they will still continue to work until further notice.
Please refer to the documentation for how to customize the block type and the Portable Text editor for v3 of the studio.
Besides this, the Portable Text input related code and schema types have been given a TypeScript update for better type safety and developer experience.
Studio appearance
The user menu now has options to select the appearance (color scheme) of the Studio. The selected appearance is stored in local storage and is reused on the next visit.
Logo component updates
The button in the navbar that wraps the custom logo component has no padding anymore. This update is made in order to give the custom logo component full control over how big the button in the navbar should be. Therefore, the custom logo component may need to be updated in order to achieve the previous look. Below is an example of how to recreate the same result as before:
import {defineConfig} from 'sanity'
import {Box} from '@​sanity/ui'
function MyLogo() {
return (
<Box padding={3}> // <-- Wrap your custom logo with a `Box` with `padding={3}`
<CustomLogo />
</Box>
)
}
export default defineConfig({
// ... rest of config
studio: {
components: {
logo: MyLogo,
},
},
})
🐛 Notable bugfixes
This update fixes so that the component in the root config (ie in defineConfig) is the component that receives the result of the props passed on with renderDefault in previous custom components.
Fixed an issue with custom sort orders
📓 Full changelog
Author | Message | Commit
------------ | ------------- | -------------
Bjørge Næss | fix(form): fix issue with zero being rendered as empty string in number input | 7be7511
Marius Lundgård | build: add bin directory to distribution | a1f6e00
Herman Wikner | feat(core): update user menu with color schemes | 788d23b
Herman Wikner | feat(core): store selected color scheme i local storage | 9ce0108
Herman Wikner | fix(core): update workspace preview design | 543a0f3
Marius Lundgård | fix(config): respect unstable_clientFactory | bcd4854
Cody Olsen | fix: optimize lodash imports (#3974) | 6c7d48d
Marius Lundgård | docs: update readme (#3987) | 88c90eb
Marius Lundgård | docs: remove ToC | 13389f5
Bjørge Næss | chore(form): replace react-sortable-hoc with dndkit (#3961) | 551c4d5
Espen Hovlandsdal | fix(cli): only require workspace name if more than 1 workspace | 743244b
Espen Hovlandsdal | feat(core): add userHasRole utility method | cd0819f
Snorre Eskeland Brekke | fix(block-tools): ignore blocks inside list items (#3492) | 5e51831
Espen Hovlandsdal | feat(core): add new documentIdEquals utility method | f7eb4b3
Espen Hovlandsdal | chore(vision): use react 18 compatible dependencies | 401f08a
Espen Hovlandsdal | fix(config): throw error early if tools/template resolution fails | 2f2e467
Herman Wikner | fix(core): components API execution order | 299ac06
vicbergquist | fix(desk): always use default ordering on first rendering if any and update order on sort | 663cc67
Espen Hovlandsdal | refactor(desk): remove unused default ordering option in useDocumentList | e2209ec
Espen Hovlandsdal | fix(desk): recompute default sort order on desk structure change | 4f9a353
Espen Hovlandsdal | fix(desk): use last updated at as default sort order | d5166e5
Per-Kristian Nordnes | refactor(types): refactor Block schemas for new component extension api | dfd33ce
Per-Kristian Nordnes | refactor(types): refactor portable text types used internally in the studio | 48c03a9
Per-Kristian Nordnes | refactor(types): remove deprecated block validator Rules from v2 | 7aa1404
Per-Kristian Nordnes | refactor(schema): allow for .components in block schema + ensure that the result has a name | 5b5e878
Per-Kristian Nordnes | refactor(validation): remove deprecated block validation rule. Should be using 'Rule.custom' in v3. | 5f92213
Per-Kristian Nordnes | refactor(validation): update pt types | acc0e79
Per-Kristian Nordnes | refactor(core/form): add block and annotation component schema extensions | bbd32ae
Per-Kristian Nordnes | refactor(block-tools): use pt-types from @sanity/types | 27d5133
Per-Kristian Nordnes | refactor(form/inputs): Custom rendering support via schema for PT-input | f1152f7
Per-Kristian Nordnes | refactor(core/fields/diffs): use new types in Portable-text-diffs | b2aa1f2
Per-Kristian Nordnes | refactor(core/preview): use new types in portable-text previews | 3fd22cc
Per-Kristian Nordnes | refactor(core/form/inputs): function can now be moved out of scope | ccdc0fd
Per-Kristian Nordnes | refactor(core/form/inputs): keep using schemaType var name | a65169b
Per-Kristian Nordnes | refactor(core/form/input): use updated types for block schemas and pt render callbacks | aa3ee4e
Per-Kristian Nordnes | refactor(types/schema): support seperate inlineBlock render callback | c21a8f1
Per-Kristian Nordnes | refactor(schema): validate lists and new component for block type | afd01e2
Per-Kristian Nordnes | refactor(types): limit supported types in block types .of to objects and refs | cb867b8
Per-Kristian Nordnes | refactor(core/form): update render callback support for block types | 0902fa5
Per-Kristian Nordnes | chore: mark types required (by schemas) as @beta | edb3bd0
Per-Kristian Nordnes | refactor(portable-text-editor): update types and add render callbacks to the PTE | 6202a8c
Per-Kristian Nordnes | chore: update puppeteer to latest version | a9dc1ea
Per-Kristian Nordnes | test(portable-text-editor): update tests | 05abec0
Per-Kristian Nordnes | chore: update yarn.lock | 0590a81
Per-Kristian Nordnes | chore(portable-text-editor): mark types with availablility status | 3408962
Per-Kristian Nordnes | refactor(portable-text-editor): simplify code | 8c08f85
Per-Kristian Nordnes | refactor(portable-text-editor): rename type > schemaType | d25cbb5
Per-Kristian Nordnes | refactor(portable-text-editor): rename type > schemaType | b18716f
Per-Kristian Nordnes | feature(schema): backward compatibility for breaking changes in block schema | c323b12
Bjørge Næss | fix(schema): add help id to blockeditor schema warnings | 8d74ace
Herman Wikner | feat(core): move padding from LogoButton to StudioLogo | d774bc6
Herman Wikner | dev(test-studio): update custom logo component | bb61fa1
Marius Lundgård | fix: pass readOnly to select element (#3900) | f70736f
'AlertBanner' cannot be used as a JSX component.
Its return type 'Element | undefined' is not a valid JSX element.
Type 'undefined' is not assignable to type 'Element | null'.ts(2786)
The solution is to either return null or return <></>
Related Commit 9c45983a5e97c2621daae7251d0356f856594196 (https://nextjs-blog-cms-sanity-v3-m2zs0oidy.sanity.build).
Originally posted by @kmelve in https://github.com/sanity-io/nextjs-blog-cms-sanity-v3/issues/89#issuecomment-1321304197
Summary
When updating a post or author, revalidation works as expected across the homepage and existing posts. However, when adding or removing/unpublishing a post entirely, sometimes only the homepage path gets revalidated. This means the "More stories" section on other exisiting posts doesn't get updated. The deleted/unpublished post also gets left behind and is still accessible.
Sometimes it does work, I can't seem to figure out why.
Video attached shows:
Newly deployed site using the deploy button in this repo (as at e43759b)
Site with 4 posts with a new 5th post being published, validation of home + all existing posts works (as seen in the function logs on the left)
When deleting that 5th post, only the homepage is invalidated, leaving the "More stories" section on all other posts out of date + the removed post still available
Adding another new post (Test Post 06), only the homepage gets revalidated, the new post is missing from "More Stories" on all other posts
Unpublishing an existing post (Test Post 04) only invalidates the homepage and itself, leaving it in the "More Stories" section on most other posts
Expected behaviour:
Adding a new post should add it to the "More stories" section of all other posts.
Note that this does reliably happen for me when updating a post, making a new post and then updating it immediately after is my current workaround
Removing/Unpublishing a post should:
remove it from the "More stories" section of all other posts
Steps to reproduce
1./ Follow steps 1 -> 3 as per README
3./ Visit studio `http://localhost:3000/studio
4./ Development server crashes with the following error.
error - ./node_modules/@sanity/ui/dist/index.esm.js
Module parse failed: 'import' and 'export' may appear only with 'sourceType: module' (61:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
| function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
> import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
| import { useMemo, useState, useRef, useEffect, createContext, useContext, useLayoutEffect, forwardRef, useId, useCallback, cloneElement, isValidElement, createElement, Component, memo, useReducer, Children, Fragment as Fragment$1 } from 'react';
| import ReactIs, { isElement as isElement$1, isFragment, isValidElementType } from 'react-is';
```
This error occurs with Yarn, PNPM and NPM package managers.
When I deploy the sanity project to the hosted Studio version, I should be able to access and use it at the set subdomain, i.e. your-project.sanity.studio.
Actual Behavior:
The Studio crashes with error:
Uncaught error: process is not defined
ReferenceError: process is not defined
Log in to your Sanity.io account, select the deployed project and set a subdomain if one isn't already set
Visit the configured subdomain for the studio
Observe error: Uncaught error: process is not defined
Context
This template seems to be only configured for the self-hosted Studio at http://localhost:3000/studio or your domain /studio path.
The sanity.config.ts file uses the node process object to access the env file. Since the Studio is a static client-side application, process is not available there and is therefore undefined.
Sanity's v2 - v3 migration guide gives a work around for this by setting the appropriate values in your env file that will be bundled and exposed within import.meta.env. Theses variables must start with SANITY_STUDIO_ in the name.
Possible Solution:
We can accommodate both by conditionally using process.env.NEXT_PUBLIC_SANITY_PROJECT_ID or import.meta.env.SANITY_STUDIO_PROJECT_ID depending on if process.env is defined.
This is a little tricky since we'll have to first check if window is not 'undefined' (referencing something like this), so on the client-side version we can set a process attribute that would allow us to check for it in the config file without causing errors.
Within TypeScript will have to reference some interfaces for import.meta as well, within a env.d.ts file.
Created a new project using this starter, and I find this renovate.json file in it, but I don't see any explanation of why it's here, what it's for, or how to use it.
I have set up and deployed the Sanity v3+next.js starter, pulled the created git-repo locally, and followed the configuration steps in the readme.
After booting it up locally via npm run dev, I go to http://localhost:3000/studio and I get the Sanity login. Completing the login, I'm then presented with this error page:
If I then refresh the page, I seem to get into the studio fine. 🤷♂️
bug
opened by Svish 5
Owner
Sanity
Sanity.io a platform for structured content that comes with an open source editor that you can customize with React.js.