@sanity/cli 8.13.0 → 8.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/actions/init/bootstrapLocalTemplate.js +5 -0
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/initAction.js +11 -3
- package/dist/actions/init/initAction.js.map +1 -1
- package/dist/actions/init/sdkAppDependencies.js +4 -4
- package/dist/actions/init/sdkAppDependencies.js.map +1 -1
- package/dist/actions/init/studioDependencies.js +2 -1
- package/dist/actions/init/studioDependencies.js.map +1 -1
- package/dist/actions/init/templates/appSanityUi.js +1 -1
- package/dist/actions/init/templates/appSanityUi.js.map +1 -1
- package/dist/actions/init/types.js +1 -1
- package/dist/actions/init/types.js.map +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.js +7 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/generated/apiRoutes.js +2 -0
- package/dist/generated/apiRoutes.js.map +1 -1
- package/dist/util/update/resolveRunnerPackage.js +1 -1
- package/dist/util/update/resolveRunnerPackage.js.map +1 -1
- package/dist/util/update/resolveUpdateTarget.js +1 -1
- package/dist/util/update/resolveUpdateTarget.js.map +1 -1
- package/dist/util/update/updateChecker.js +7 -2
- package/dist/util/update/updateChecker.js.map +1 -1
- package/dist/util/update/updateCheckerDebug.js +1 -1
- package/dist/util/update/updateCheckerDebug.js.map +1 -1
- package/oclif.manifest.json +570 -567
- package/package.json +7 -7
- package/templates/app-sanity-ui/src/App.tsx +8 -8
- package/templates/app-sanity-ui/src/ExampleComponent.tsx +1 -1
- package/templates/app-sanity-ui/src/SanityUI.tsx +3 -1
- package/templates/shared/dashboard/app-quickstart/.claude/skills/sanity-app-sdk/SKILL.md +66 -0
- package/templates/shared/dashboard/app-quickstart/AGENTS.md +61 -0
- package/templates/shared/dashboard/app-quickstart/README.md +30 -0
- package/templates/shared/dashboard/app-sanity-ui/.claude/skills/sanity-app-sdk/SKILL.md +70 -0
- package/templates/shared/dashboard/app-sanity-ui/AGENTS.md +65 -0
- package/templates/shared/dashboard/app-sanity-ui/README.md +31 -0
- package/templates/shared/tsconfig.json +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.14.0",
|
|
4
4
|
"description": "Sanity CLI tool for managing Sanity projects and organizations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"@oclif/core": "^4.11.14",
|
|
63
63
|
"@oclif/plugin-help": "^6.2.53",
|
|
64
64
|
"@oclif/plugin-not-found": "^3.2.88",
|
|
65
|
-
"@sanity/cli-build": "^6.4.
|
|
66
|
-
"@sanity/cli-core": "^3.8.
|
|
65
|
+
"@sanity/cli-build": "^6.4.4",
|
|
66
|
+
"@sanity/cli-core": "^3.8.2",
|
|
67
67
|
"@sanity/client": "^8.6.2",
|
|
68
68
|
"@sanity/codegen": "^8.1.0",
|
|
69
69
|
"@sanity/descriptors": "^1.3.0",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@sanity/telemetry": "^1.1.0",
|
|
78
78
|
"@sanity/template-validator": "^3.1.1",
|
|
79
79
|
"@sanity/types": "^6.15.0",
|
|
80
|
-
"@sanity/workbench-cli": "^2.8.
|
|
80
|
+
"@sanity/workbench-cli": "^2.8.3",
|
|
81
81
|
"@sanity/worker-channels": "^2.0.0",
|
|
82
82
|
"@sanity/workflow-cli": "0.32.0",
|
|
83
83
|
"@sanity/workflow-engine": "0.32.0",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"tinyglobby": "^0.2.17",
|
|
117
117
|
"typeid-js": "^1.2.0",
|
|
118
118
|
"valibot": "^1.4.2",
|
|
119
|
-
"vite": "^8.3.
|
|
119
|
+
"vite": "^8.3.2",
|
|
120
120
|
"which": "^6.0.1",
|
|
121
121
|
"wrap-ansi": "^9.0.2",
|
|
122
122
|
"yaml": "^2.9.0",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"@eslint/compat": "^2.1.0",
|
|
127
127
|
"@repo/package.config": "0.0.1",
|
|
128
128
|
"@repo/tsconfig": "3.70.0",
|
|
129
|
-
"@sanity/cli-test": "18.0.
|
|
129
|
+
"@sanity/cli-test": "18.0.2",
|
|
130
130
|
"@sanity/eslint-config-cli": "1.1.3",
|
|
131
131
|
"@sanity/pkg-utils": "^12.3.4",
|
|
132
132
|
"@swc/cli": "^0.8.1",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
"jsdom": "^29.1.1",
|
|
148
148
|
"nock": "^14.0.15",
|
|
149
149
|
"oclif": "^4.23.27",
|
|
150
|
-
"oxc-transform-react": "^0.
|
|
150
|
+
"oxc-transform-react": "^0.152.0",
|
|
151
151
|
"publint": "^0.3.21",
|
|
152
152
|
"rimraf": "^6.0.1",
|
|
153
153
|
"sanity": "^6.15.0",
|
|
@@ -4,6 +4,14 @@ import {Flex, Spinner} from '@sanity/ui'
|
|
|
4
4
|
import {ExampleComponent} from './ExampleComponent'
|
|
5
5
|
import {SanityUI} from './SanityUI'
|
|
6
6
|
|
|
7
|
+
function Loading() {
|
|
8
|
+
return (
|
|
9
|
+
<Flex justify="center" align="center" height="fill">
|
|
10
|
+
<Spinner />
|
|
11
|
+
</Flex>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
function App() {
|
|
8
16
|
// apps can access many different projects or other sources of data
|
|
9
17
|
const sanityConfigs: SanityConfig[] = [
|
|
@@ -13,14 +21,6 @@ function App() {
|
|
|
13
21
|
},
|
|
14
22
|
]
|
|
15
23
|
|
|
16
|
-
function Loading() {
|
|
17
|
-
return (
|
|
18
|
-
<Flex justify="center" align="center" width="100vw" height="fill">
|
|
19
|
-
<Spinner />
|
|
20
|
-
</Flex>
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
24
|
return (
|
|
25
25
|
<SanityUI>
|
|
26
26
|
<SanityApp config={sanityConfigs} fallback={<Loading />}>
|
|
@@ -10,7 +10,7 @@ export function ExampleComponent() {
|
|
|
10
10
|
<Flex align="center" direction="column" gap={5} marginY={4}>
|
|
11
11
|
<Avatar size={3} src={user?.profileImage} />
|
|
12
12
|
<Heading as="h1">Welcome to your Sanity App, {user?.name}!</Heading>
|
|
13
|
-
<Stack
|
|
13
|
+
<Stack gap={4}>
|
|
14
14
|
<Text muted>
|
|
15
15
|
This is an example component, rendered with Sanity UI and the{' '}
|
|
16
16
|
<code>useCurrentUser</code> hook from the Sanity App SDK. You can import and use any
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@sanity/ui/styles.css'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
2
3
|
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {ToastProvider} from '@sanity/ui/toast'
|
|
3
5
|
import {createGlobalStyle} from 'styled-components'
|
|
4
6
|
|
|
5
7
|
const theme = buildTheme()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sanity-app-sdk
|
|
3
|
+
description: Build features with the Sanity App SDK (@sanity/sdk-react). Use when adding components, fetching or editing Sanity content, or working with hooks like useDocuments, useDocument, useDocumentProjection, useEditDocument, or useQuery.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sanity App SDK
|
|
7
|
+
|
|
8
|
+
## Get the maintained guide first
|
|
9
|
+
|
|
10
|
+
If the Sanity MCP server is configured, call its `get_sanity_rules` tool with the `app-sdk` rule before writing SDK code. That rule is maintained by Sanity, is more detailed, and supersedes the notes below. The notes below are a fallback for when MCP is not available.
|
|
11
|
+
|
|
12
|
+
## Picking a hook
|
|
13
|
+
|
|
14
|
+
- `useDocuments` / `usePaginatedDocuments`: lists of documents. Returns document handles, not full documents.
|
|
15
|
+
- `useDocumentProjection`: read specific fields from a handle, for display.
|
|
16
|
+
- `useDocument` plus `useEditDocument`: read and write a single document in real time.
|
|
17
|
+
- `useQuery`: raw GROQ. Use sparingly; prefer handles plus projections.
|
|
18
|
+
|
|
19
|
+
## Document handles
|
|
20
|
+
|
|
21
|
+
Fetch handles first, then spread them into other hooks:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
const {data} = useDocuments({documentType: 'article'})
|
|
25
|
+
|
|
26
|
+
// in a child component receiving one handle:
|
|
27
|
+
const {data: fields} = useDocumentProjection({...handle, projection: '{title}'})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use `documentId` as the React key when rendering lists, never the array index.
|
|
31
|
+
|
|
32
|
+
## Suspense
|
|
33
|
+
|
|
34
|
+
Data hooks suspend while loading. Wrap every data-fetching component in `<Suspense>` with a fallback, keep one fetching hook per component, and always pass a `fallback` to `SanityApp`. All SDK hooks must be used inside `SanityApp`.
|
|
35
|
+
|
|
36
|
+
## Editing
|
|
37
|
+
|
|
38
|
+
Write through `useEditDocument` on change so content stays in sync with the Content Lake:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
const {data: title} = useDocument({...handle, path: 'title'})
|
|
42
|
+
const editTitle = useEditDocument({...handle, path: 'title'})
|
|
43
|
+
// <input value={title ?? ''} onChange={(e) => editTitle(e.currentTarget.value)} />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Do not hold document field values in `useState` and save on submit. That pattern goes stale and loses concurrent edits.
|
|
47
|
+
|
|
48
|
+
## Dashboard hooks
|
|
49
|
+
|
|
50
|
+
This app runs in the Sanity Dashboard (`defineApplication` in `sanity.cli.ts`). Hooks that talk to the Dashboard itself are imported from `@sanity/sdk-react/dashboard`, not `@sanity/sdk-react`:
|
|
51
|
+
|
|
52
|
+
- `useNavigate`: keep the app's router in sync with the Dashboard URL.
|
|
53
|
+
- `useOrganizationId`: the organization selected in the Dashboard.
|
|
54
|
+
- `useApplications` / `useApplication`: apps available in the Dashboard.
|
|
55
|
+
- `useWindowTitle`: set the browser tab title.
|
|
56
|
+
- `useNavigateToStudioDocument`: open a document in its Studio.
|
|
57
|
+
|
|
58
|
+
## Documentation
|
|
59
|
+
|
|
60
|
+
Fetch these for current detail rather than relying on the notes above:
|
|
61
|
+
|
|
62
|
+
- Best practices: https://www.sanity.io/docs/app-sdk/sdk-best-practices
|
|
63
|
+
- Editing documents: https://www.sanity.io/docs/app-sdk/editing-documents
|
|
64
|
+
- Configuration: https://www.sanity.io/docs/app-sdk/sdk-configuration
|
|
65
|
+
- Deployment: https://www.sanity.io/docs/app-sdk/sdk-deployment
|
|
66
|
+
- API reference with current signatures: https://reference.sanity.io/_sanity/sdk-react/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
A React application built with the Sanity App SDK (`@sanity/sdk-react`). It is not a Sanity Studio. The app reads and writes content in a Sanity project through SDK hooks, and runs inside the organization's Sanity Dashboard, in development and when deployed. The `sanity` CLI runs it with Vite under the hood.
|
|
8
|
+
|
|
9
|
+
The app is set up for the Sanity Dashboard beta: `sanity.cli.ts` declares it with `defineApplication`.
|
|
10
|
+
|
|
11
|
+
## Key files
|
|
12
|
+
|
|
13
|
+
- `src/App.tsx`: entry point. The `SanityApp` component takes a `config` array with `projectId` and `dataset`. All SDK hooks must be used inside `SanityApp`.
|
|
14
|
+
- `sanity.cli.ts`: CLI config. `app` is `defineApplication({title, slug, organizationId, entry})`. `slug` is the app's unique address in the organization, used to create the app on its first deploy: lowercase letters, numbers and hyphens, starting with a letter.
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
|
|
18
|
+
- `npm run dev`: starts a local Sanity Dashboard on port 3333 and serves the app on the next port (3334), loaded into that Dashboard. The CLI prints the local Dashboard URL. The app only renders inside the Dashboard, and viewing it requires a signed-in Sanity account, so a human must complete authentication in the browser.
|
|
19
|
+
- `npm run build`: production build.
|
|
20
|
+
- `npm run deploy`: deploy to the organization's Sanity Dashboard.
|
|
21
|
+
|
|
22
|
+
Environment variables prefixed with `SANITY_APP_` are bundled into the app.
|
|
23
|
+
|
|
24
|
+
## Deploying without prompts
|
|
25
|
+
|
|
26
|
+
The first deploy creates the app from `slug` and `title` in `defineApplication`. Do not pass `--create`; it is rejected for this config.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm run deploy -- --yes --json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`--title` overrides `app.title`. Add `--dry-run` to preview the deployment without creating or uploading anything. A first deploy cannot use `--no-build`, because the new app ID is built into the bundle.
|
|
33
|
+
|
|
34
|
+
Save `application.id` from the JSON response as `deployment.appId` in `sanity.cli.ts`. Later deploys use the same command and update that app. Without `deployment.appId`, a later deploy fails because the slug is already taken; the error includes the app ID to save.
|
|
35
|
+
|
|
36
|
+
A deployed app is served at `https://<organizationId>.sanity.run/applications/<appId>`.
|
|
37
|
+
|
|
38
|
+
Agent terminals may disable interactive prompts even with a PTY (`TERM=dumb`). Use these flags rather than changing terminal settings or calling the applications API directly. Run `npm run deploy -- --help` to check which flags the installed CLI supports.
|
|
39
|
+
|
|
40
|
+
This app is not a Studio. For a Studio's first hosted deployment, use `sanity deploy --url <hostname> --yes`; `studioHost`, if used in config, belongs at the top level, not inside `deployment`.
|
|
41
|
+
|
|
42
|
+
## Working with the App SDK
|
|
43
|
+
|
|
44
|
+
If the Sanity MCP server is available, call its `get_sanity_rules` tool with the `app-sdk` rule before writing SDK code. That rule is the maintained guide and supersedes the notes below.
|
|
45
|
+
|
|
46
|
+
Essentials:
|
|
47
|
+
|
|
48
|
+
- Data hooks suspend while loading. Wrap every data-fetching component in `<Suspense>`, keep one fetching hook per component, and always pass a `fallback` to `SanityApp`.
|
|
49
|
+
- Fetch lists with `useDocuments` (or `usePaginatedDocuments`). They return document handles, not full documents. Spread a handle into `useDocumentProjection` to display fields, or into `useDocument` and `useEditDocument` for real-time editing.
|
|
50
|
+
- Use `documentId` as the React key when rendering document lists, never the array index.
|
|
51
|
+
- Do not hold document field values in `useState` and save on submit. Write through `useEditDocument` on change so content stays in sync with the Content Lake.
|
|
52
|
+
- Prefer handles plus projections over raw GROQ. Reach for `useQuery` only when a complex query genuinely needs it.
|
|
53
|
+
- Hooks that talk to the Dashboard itself are imported from `@sanity/sdk-react/dashboard`, not `@sanity/sdk-react`. Examples: `useNavigate`, `useOrganizationId`, `useApplications`, `useApplication`, `useWindowTitle`, `useNavigateToStudioDocument`.
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
- App SDK docs: https://www.sanity.io/docs/app-sdk
|
|
58
|
+
- Best practices: https://www.sanity.io/docs/app-sdk/sdk-best-practices
|
|
59
|
+
- Editing documents: https://www.sanity.io/docs/app-sdk/editing-documents
|
|
60
|
+
- Configuration: https://www.sanity.io/docs/app-sdk/sdk-configuration
|
|
61
|
+
- API reference with current signatures: https://reference.sanity.io/_sanity/sdk-react/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Sanity App
|
|
2
|
+
|
|
3
|
+
A custom application built with the [Sanity App SDK](https://www.sanity.io/docs/app-sdk?utm_source=readme). It is a React app that runs inside your organization's Sanity Dashboard, in development and when deployed.
|
|
4
|
+
|
|
5
|
+
This app is set up for the Sanity Dashboard beta: `sanity.cli.ts` declares it with `defineApplication`.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- `npm run dev` starts a local Sanity Dashboard (by default at http://localhost:3333, with the app on port 3334) and loads your app into it. Open it and sign in with your Sanity account.
|
|
10
|
+
- `npm run build` builds the app for production.
|
|
11
|
+
- `npm run deploy` deploys the app to your organization's Sanity Dashboard. The first deploy creates the app.
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
- `src/App.tsx` is the app entry point. The `SanityApp` config sets which project and dataset the app reads content from.
|
|
16
|
+
- `sanity.cli.ts` declares the app with `defineApplication`:
|
|
17
|
+
- `title`: the app's name in the Dashboard.
|
|
18
|
+
- `slug`: the app's unique address in your organization, used to create the app on its first deploy. Lowercase letters, numbers and hyphens, starting with a letter.
|
|
19
|
+
- `organizationId`: the organization the app belongs to.
|
|
20
|
+
- `entry`: the app entry path.
|
|
21
|
+
|
|
22
|
+
After the first deploy, add the app ID it prints to `sanity.cli.ts` as `deployment.appId` so later deploys update the same app.
|
|
23
|
+
|
|
24
|
+
## Learn more
|
|
25
|
+
|
|
26
|
+
- [App SDK Quickstart Guide](https://www.sanity.io/docs/app-sdk/sdk-quickstart?utm_source=readme)
|
|
27
|
+
- [App SDK documentation](https://www.sanity.io/docs/app-sdk?utm_source=readme)
|
|
28
|
+
- [API reference](https://reference.sanity.io/_sanity/sdk-react/)
|
|
29
|
+
- [Deploying your app](https://www.sanity.io/docs/app-sdk/sdk-deployment?utm_source=readme)
|
|
30
|
+
- [SDK Explorer with example apps](https://sdk-explorer.sanity.io)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sanity-app-sdk
|
|
3
|
+
description: Build features with the Sanity App SDK (@sanity/sdk-react) and Sanity UI. Use when adding components, fetching or editing Sanity content, or working with hooks like useDocuments, useDocument, useDocumentProjection, useEditDocument, or useQuery.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sanity App SDK
|
|
7
|
+
|
|
8
|
+
## Get the maintained guide first
|
|
9
|
+
|
|
10
|
+
If the Sanity MCP server is configured, call its `get_sanity_rules` tool with the `app-sdk` rule before writing SDK code. That rule is maintained by Sanity, is more detailed, and supersedes the notes below. The notes below are a fallback for when MCP is not available.
|
|
11
|
+
|
|
12
|
+
## Picking a hook
|
|
13
|
+
|
|
14
|
+
- `useDocuments` / `usePaginatedDocuments`: lists of documents. Returns document handles, not full documents.
|
|
15
|
+
- `useDocumentProjection`: read specific fields from a handle, for display.
|
|
16
|
+
- `useDocument` plus `useEditDocument`: read and write a single document in real time.
|
|
17
|
+
- `useQuery`: raw GROQ. Use sparingly; prefer handles plus projections.
|
|
18
|
+
|
|
19
|
+
## Document handles
|
|
20
|
+
|
|
21
|
+
Fetch handles first, then spread them into other hooks:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
const {data} = useDocuments({documentType: 'article'})
|
|
25
|
+
|
|
26
|
+
// in a child component receiving one handle:
|
|
27
|
+
const {data: fields} = useDocumentProjection({...handle, projection: '{title}'})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use `documentId` as the React key when rendering lists, never the array index.
|
|
31
|
+
|
|
32
|
+
## Suspense
|
|
33
|
+
|
|
34
|
+
Data hooks suspend while loading. Wrap every data-fetching component in `<Suspense>` with a fallback, keep one fetching hook per component, and always pass a `fallback` to `SanityApp`. All SDK hooks must be used inside `SanityApp`.
|
|
35
|
+
|
|
36
|
+
## Editing
|
|
37
|
+
|
|
38
|
+
Write through `useEditDocument` on change so content stays in sync with the Content Lake:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
const {data: title} = useDocument({...handle, path: 'title'})
|
|
42
|
+
const editTitle = useEditDocument({...handle, path: 'title'})
|
|
43
|
+
// <input value={title ?? ''} onChange={(e) => editTitle(e.currentTarget.value)} />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Do not hold document field values in `useState` and save on submit. That pattern goes stale and loses concurrent edits.
|
|
47
|
+
|
|
48
|
+
## Sanity UI
|
|
49
|
+
|
|
50
|
+
This app wraps everything in Sanity UI's `ThemeProvider` (see `src/SanityUI.tsx`, built with `buildTheme()`). Build UI with Sanity UI primitives like `Card`, `Stack`, `Flex`, `Text`, and `Button`. See https://www.sanity.io/docs/app-sdk/sanity-ui-sdk and https://www.sanity.io/ui.
|
|
51
|
+
|
|
52
|
+
## Dashboard hooks
|
|
53
|
+
|
|
54
|
+
This app runs in the Sanity Dashboard (`defineApplication` in `sanity.cli.ts`). Hooks that talk to the Dashboard itself are imported from `@sanity/sdk-react/dashboard`, not `@sanity/sdk-react`:
|
|
55
|
+
|
|
56
|
+
- `useNavigate`: keep the app's router in sync with the Dashboard URL.
|
|
57
|
+
- `useOrganizationId`: the organization selected in the Dashboard.
|
|
58
|
+
- `useApplications` / `useApplication`: apps available in the Dashboard.
|
|
59
|
+
- `useWindowTitle`: set the browser tab title.
|
|
60
|
+
- `useNavigateToStudioDocument`: open a document in its Studio.
|
|
61
|
+
|
|
62
|
+
## Documentation
|
|
63
|
+
|
|
64
|
+
Fetch these for current detail rather than relying on the notes above:
|
|
65
|
+
|
|
66
|
+
- Best practices: https://www.sanity.io/docs/app-sdk/sdk-best-practices
|
|
67
|
+
- Editing documents: https://www.sanity.io/docs/app-sdk/editing-documents
|
|
68
|
+
- Configuration: https://www.sanity.io/docs/app-sdk/sdk-configuration
|
|
69
|
+
- Deployment: https://www.sanity.io/docs/app-sdk/sdk-deployment
|
|
70
|
+
- API reference with current signatures: https://reference.sanity.io/_sanity/sdk-react/
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
A React application built with the Sanity App SDK (`@sanity/sdk-react`) and Sanity UI (`@sanity/ui`). It is not a Sanity Studio. The app reads and writes content in a Sanity project through SDK hooks, and runs inside the organization's Sanity Dashboard, in development and when deployed. The `sanity` CLI runs it with Vite under the hood.
|
|
8
|
+
|
|
9
|
+
The app is set up for the Sanity Dashboard beta: `sanity.cli.ts` declares it with `defineApplication`.
|
|
10
|
+
|
|
11
|
+
## Key files
|
|
12
|
+
|
|
13
|
+
- `src/App.tsx`: entry point. The `SanityApp` component takes a `config` array with `projectId` and `dataset`. All SDK hooks must be used inside `SanityApp`.
|
|
14
|
+
- `src/SanityUI.tsx`: wraps the app in Sanity UI's `ThemeProvider` with a theme from `buildTheme()`. Sanity UI components must render inside this provider.
|
|
15
|
+
- `sanity.cli.ts`: CLI config. `app` is `defineApplication({title, slug, organizationId, entry})`. `slug` is the app's unique address in the organization, used to create the app on its first deploy: lowercase letters, numbers and hyphens, starting with a letter.
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
- `npm run dev`: starts a local Sanity Dashboard on port 3333 and serves the app on the next port (3334), loaded into that Dashboard. The CLI prints the local Dashboard URL. The app only renders inside the Dashboard, and viewing it requires a signed-in Sanity account, so a human must complete authentication in the browser.
|
|
20
|
+
- `npm run build`: production build.
|
|
21
|
+
- `npm run deploy`: deploy to the organization's Sanity Dashboard.
|
|
22
|
+
|
|
23
|
+
Environment variables prefixed with `SANITY_APP_` are bundled into the app.
|
|
24
|
+
|
|
25
|
+
## Deploying without prompts
|
|
26
|
+
|
|
27
|
+
The first deploy creates the app from `slug` and `title` in `defineApplication`. Do not pass `--create`; it is rejected for this config.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm run deploy -- --yes --json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`--title` overrides `app.title`. Add `--dry-run` to preview the deployment without creating or uploading anything. A first deploy cannot use `--no-build`, because the new app ID is built into the bundle.
|
|
34
|
+
|
|
35
|
+
Save `application.id` from the JSON response as `deployment.appId` in `sanity.cli.ts`. Later deploys use the same command and update that app. Without `deployment.appId`, a later deploy fails because the slug is already taken; the error includes the app ID to save.
|
|
36
|
+
|
|
37
|
+
A deployed app is served at `https://<organizationId>.sanity.run/applications/<appId>`.
|
|
38
|
+
|
|
39
|
+
Agent terminals may disable interactive prompts even with a PTY (`TERM=dumb`). Use these flags rather than changing terminal settings or calling the applications API directly. Run `npm run deploy -- --help` to check which flags the installed CLI supports.
|
|
40
|
+
|
|
41
|
+
This app is not a Studio. For a Studio's first hosted deployment, use `sanity deploy --url <hostname> --yes`; `studioHost`, if used in config, belongs at the top level, not inside `deployment`.
|
|
42
|
+
|
|
43
|
+
## Working with the App SDK
|
|
44
|
+
|
|
45
|
+
If the Sanity MCP server is available, call its `get_sanity_rules` tool with the `app-sdk` rule before writing SDK code. That rule is the maintained guide and supersedes the notes below.
|
|
46
|
+
|
|
47
|
+
Essentials:
|
|
48
|
+
|
|
49
|
+
- Data hooks suspend while loading. Wrap every data-fetching component in `<Suspense>`, keep one fetching hook per component, and always pass a `fallback` to `SanityApp`.
|
|
50
|
+
- Fetch lists with `useDocuments` (or `usePaginatedDocuments`). They return document handles, not full documents. Spread a handle into `useDocumentProjection` to display fields, or into `useDocument` and `useEditDocument` for real-time editing.
|
|
51
|
+
- Use `documentId` as the React key when rendering document lists, never the array index.
|
|
52
|
+
- Do not hold document field values in `useState` and save on submit. Write through `useEditDocument` on change so content stays in sync with the Content Lake.
|
|
53
|
+
- Prefer handles plus projections over raw GROQ. Reach for `useQuery` only when a complex query genuinely needs it.
|
|
54
|
+
- Build UI with Sanity UI primitives like `Card`, `Stack`, `Flex`, `Text`, and `Button` for a look consistent with Sanity tooling.
|
|
55
|
+
- Hooks that talk to the Dashboard itself are imported from `@sanity/sdk-react/dashboard`, not `@sanity/sdk-react`. Examples: `useNavigate`, `useOrganizationId`, `useApplications`, `useApplication`, `useWindowTitle`, `useNavigateToStudioDocument`.
|
|
56
|
+
|
|
57
|
+
## Documentation
|
|
58
|
+
|
|
59
|
+
- App SDK docs: https://www.sanity.io/docs/app-sdk
|
|
60
|
+
- Best practices: https://www.sanity.io/docs/app-sdk/sdk-best-practices
|
|
61
|
+
- Editing documents: https://www.sanity.io/docs/app-sdk/editing-documents
|
|
62
|
+
- Configuration: https://www.sanity.io/docs/app-sdk/sdk-configuration
|
|
63
|
+
- Sanity UI with the App SDK: https://www.sanity.io/docs/app-sdk/sanity-ui-sdk
|
|
64
|
+
- Sanity UI docs: https://www.sanity.io/ui
|
|
65
|
+
- API reference with current signatures: https://reference.sanity.io/_sanity/sdk-react/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Sanity App
|
|
2
|
+
|
|
3
|
+
A custom application built with the [Sanity App SDK](https://www.sanity.io/docs/app-sdk?utm_source=readme) and [Sanity UI](https://www.sanity.io/ui?utm_source=readme). It is a React app that runs inside your organization's Sanity Dashboard, in development and when deployed.
|
|
4
|
+
|
|
5
|
+
This app is set up for the Sanity Dashboard beta: `sanity.cli.ts` declares it with `defineApplication`.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- `npm run dev` starts a local Sanity Dashboard (by default at http://localhost:3333, with the app on port 3334) and loads your app into it. Open it and sign in with your Sanity account.
|
|
10
|
+
- `npm run build` builds the app for production.
|
|
11
|
+
- `npm run deploy` deploys the app to your organization's Sanity Dashboard. The first deploy creates the app.
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
- `src/App.tsx` is the app entry point. The `SanityApp` config sets which project and dataset the app reads content from.
|
|
16
|
+
- `sanity.cli.ts` declares the app with `defineApplication`:
|
|
17
|
+
- `title`: the app's name in the Dashboard.
|
|
18
|
+
- `slug`: the app's unique address in your organization, used to create the app on its first deploy. Lowercase letters, numbers and hyphens, starting with a letter.
|
|
19
|
+
- `organizationId`: the organization the app belongs to.
|
|
20
|
+
- `entry`: the app entry path.
|
|
21
|
+
|
|
22
|
+
After the first deploy, add the app ID it prints to `sanity.cli.ts` as `deployment.appId` so later deploys update the same app.
|
|
23
|
+
|
|
24
|
+
## Learn more
|
|
25
|
+
|
|
26
|
+
- [App SDK Quickstart Guide](https://www.sanity.io/docs/app-sdk/sdk-quickstart?utm_source=readme)
|
|
27
|
+
- [App SDK documentation](https://www.sanity.io/docs/app-sdk?utm_source=readme)
|
|
28
|
+
- [Using Sanity UI with the App SDK](https://www.sanity.io/docs/app-sdk/sanity-ui-sdk?utm_source=readme)
|
|
29
|
+
- [API reference](https://reference.sanity.io/_sanity/sdk-react/)
|
|
30
|
+
- [Deploying your app](https://www.sanity.io/docs/app-sdk/sdk-deployment?utm_source=readme)
|
|
31
|
+
- [SDK Explorer with example apps](https://sdk-explorer.sanity.io)
|