Skip to content

Commit

Permalink
feat: support visual editing (#949)
Browse files Browse the repository at this point in the history
  • Loading branch information
rdunk committed Mar 6, 2024
1 parent f442da1 commit aeb9d11
Show file tree
Hide file tree
Showing 25 changed files with 1,471 additions and 316 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ node_modules
.DS_Store
coverage
dist

playground/.env
.vercel
7 changes: 7 additions & 0 deletions docs/content/1.getting-started/2.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,10 @@ export default defineNuxtConfig({
},
})
```

### `visualEditing`

- Type: **Object**
- Default: **undefined**

Used to enable and configure Visual Editing. See the [Visual Editing](/getting-started/visual-editing) section for more details.
90 changes: 90 additions & 0 deletions docs/content/1.getting-started/4.visual-editing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Visual Editing

---

## Overview

`@nuxtjs/sanity` provides a simple method of integrating [visual editing](https://www.sanity.io/docs/visual-editing) in your Nuxt application. Before enabling this feature, make sure you have [Presentation](https://www.sanity.io/docs/presentation) installed in your studio.

::alert{type="warning"}
Installing `@sanity/client` is required for visual editing. The `minimal` client must not be enabled.
::

## Configuration

You can configure visual editing via the `sanity.visualEditing` key in your Nuxt config. The following options are available:

#### `studioUrl`

- **Required**
- Type: **string**

The URL of the Sanity Studio with Presentation installed.

#### `token`

- **Required**
- Type: **string**

A Sanity read token used for server side queries. This is required in order to fetch draft content. This value will not be exposed to the client.

#### `mode`

- Type: **string**
- Default: **`'live-visual-editing'`**

Accepts one of the following options:

- **`'live-visual-editing'`** - Default behaviour. Lets the module handle setup to provide fully featured visual editing with live updates. Queries should be executed using `useSanityQuery`.
- **`'visual-editing'`** - Used to enable visual editing without live updates, for example if fetching data using the Sanity client directly. Passing a custom `refresh` handler is recommended, as by default the entire app will refresh to display updates.
- **`'custom'`** - The module will not handle any setup, instead the `useSanityVisualEditing` and/or `useSanityLiveMode` composables will need to be called manually.


#### `previewMode`

- Type: **boolean**, **object**
- Default: **true**

To enable preview mode with defaults, or optionally configure the endpoints used to enable and disable preview mode. If passing an object, the options that can be provided are:

- `enable` - the path of the enable endpoint, defaults to `/preview/enable`
- `disable` - the path of the disable endpoint, defaults to `/preview/disable`

#### `stega`

- Type: **boolean**
- Default: **true**

Used to enable or disable [stega](https://www.sanity.io/docs/loaders-and-overlays#1dbcc04a7093).


#### `refresh`

- Type: **function**

An optional function for overriding the default handling of refresh events received from the studio. This is generally not need needed if the `mode` option is set to `live-visual-editing`.

#### `zIndex`

- Type: **number**, **string**
- Default: **9999999**

The CSS z-index on the root node that renders overlays.


### Recommended Configuration

For most use cases, the following minimum `visualEditing` configuration will suffice:

```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxtjs/sanity'],
sanity: {
// ... Sanity config
visualEditing: {
token: process.env.NUXT_SANITY_VISUAL_EDITING_TOKEN,
studioUrl: process.env.NUXT_SANITY_VISUAL_EDITING_STUDIO_URL,
}
},
})
```
63 changes: 62 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,68 @@
import { SanityHelper } from './src/runtime/composables'
import type { ClientPerspective, StegaConfig } from '@sanity/client'
import type { SanityHelper } from '#sanity-composables'
import type {
SanityVisualEditingMode,
SanityVisualEditingRefreshHandler,
SanityVisualEditingZIndex,
} from './src/module'

type nullish = null | undefined | void

declare module '#app' {
interface NuxtApp {
_sanity?: Record<string, SanityHelper>
}
}

declare module 'nuxt/schema' {
interface RuntimeConfig {
sanity: {
visualEditing:
| {
previewMode:
| false
| {
enable: string
disable: string
}
mode: SanityVisualEditingMode
studioUrl: string
previewModeId: string
token: string

}
| undefined
}
}

interface PublicRuntimeConfig {
sanity: {
additionalClients: Record<string, any>
apiVersion: string
dataset: string
disableSmartCdn: boolean
perspective: ClientPerspective
projectId: string
stega: StegaConfig
token: string
useCdn: boolean
visualEditing:
| {
previewMode:
| false
| {
enable: string
disable: string
}
mode: SanityVisualEditingMode,
studioUrl: string
refresh: SanityVisualEditingRefreshHandler,
zIndex: SanityVisualEditingZIndex
}
| nullish
}
withCredentials: boolean
}
}

export {}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"dependencies": {
"@nuxt/kit": "^3.9.0",
"@portabletext/types": "^2.0.8",
"@sanity/core-loader": "^1.4.0",
"@sanity/preview-url-secret": "^1.6.0",
"@sanity/visual-editing": "^1.5.2",
"chalk": "^5.3.0",
"defu": "^6.1.3",
"knitwork": "^1.0.0",
Expand Down
2 changes: 2 additions & 0 deletions playground/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# add a Viewer token issued from https://www.sanity.io/organizations/<org_id>/project/<project_id>/api#tokens
NUXT_SANITY_VISUAL_EDITING_TOKEN=
5 changes: 3 additions & 2 deletions playground/cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"author": "Daniel Roe <daniel@roe.dev>",
"license": "MIT",
"scripts": {
"dev": "sanity dev",
"start": "sanity start",
"test": "sanity check"
},
Expand All @@ -18,11 +19,11 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.12.0",
"sanity": "3.23.4",
"sanity": "3.30.1",
"styled-components": "^6.1.6"
},
"devDependencies": {
"@sanity/vision": "3.23.4",
"@sanity/vision": "3.30.1",
"@types/react": "18.2.61",
"@types/styled-components": "5.1.34"
}
Expand Down
20 changes: 16 additions & 4 deletions playground/cms/sanity.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import { createConfig } from 'sanity'
import { deskTool } from 'sanity/desk'
import { structureTool } from 'sanity/structure'
import { presentationTool } from 'sanity/presentation'
import { defineConfig } from 'sanity'
import { visionTool } from '@sanity/vision'
import { schemaTypes } from './schemas'
import { debugSecrets } from '@sanity/preview-url-secret/sanity-plugin-debug-secrets'

export default createConfig({
export default defineConfig({
name: 'default',

projectId: 'j1o4tmjp',
dataset: 'production',

plugins: [
deskTool(),
structureTool(),
visionTool(),
presentationTool({
previewUrl: {
origin: 'http://localhost:3000',
previewMode: {
enable: '/preview/enable',
disable: '/preview/disable',
},
},
}),
debugSecrets(),
],

schema: {
Expand Down
5 changes: 5 additions & 0 deletions playground/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ export default defineNuxtConfig({
globalHelper: true,
projectId: 'j1o4tmjp',
dataset: 'production',
apiVersion: '2021-03-25',
additionalClients: {
another: {},
},
visualEditing: {
token: process.env.NUXT_SANITY_VISUAL_EDITING_TOKEN,
studioUrl: 'http://localhost:3333',
},
},
})
7 changes: 3 additions & 4 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
>
<h2>Project ID: {{ $sanity.config.projectId }}</h2>
<NuxtLink
v-for="{ title, poster, slug } in movies"
v-for="({ title, poster, slug }, i) in movies"
:key="title"
:to="`/movie/${slug}`"
class="flex w-64 h-48 relative justify-start"
>
<div
class="py-2 px-4 left-0 bottom-0 mb-4 flex-grow absolute bg-gray-100 rounded shadow-md font-semibold text-gray-800"
:data-sanity="encodeDataAttribute?.([i, 'title'])"
>
{{ title }}
</div>
Expand Down Expand Up @@ -38,7 +39,5 @@ interface QueryResult {
slug: string
}
const sanity = useSanity()
const { data: movies } = await useAsyncData<QueryResult[]>('movies', () => sanity.fetch(query))
const { data: movies, encodeDataAttribute } = await useSanityQuery<QueryResult[]>(query)
</script>
15 changes: 10 additions & 5 deletions playground/pages/movie/[slug].vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<template>
<div class="p-4">
<template v-if="details">
<p><strong>Title</strong>: {{ details.title }}</p>
<p :data-sanity="encodeDataAttribute?.(['title'])">
<strong>Title</strong>: {{ details.title }}
</p>
<p>
<strong>Release date</strong>:
{{
Expand All @@ -24,7 +26,9 @@
project-id="j1o4tmjp"
asset-id="image-e22a88d23751a84df81f03ef287ae85fc992fe12-780x1170-jpg"
/>
<SanityContent :blocks="details.overview" />
<div :data-sanity="encodeDataAttribute?.(['overview'])">
<SanityContent :blocks="details.overview" />
</div>
</template>
<template v-else>
Loading ...
Expand Down Expand Up @@ -56,7 +60,8 @@ interface QueryResult {
}
const route = useRoute()
const { data: details } = await useSanityQuery<QueryResult>(query, {
slug: route.params.slug,
})
const { data: details, encodeDataAttribute } =
await useSanityQuery<QueryResult>(query, {
slug: route.params.slug,
})
</script>

0 comments on commit aeb9d11

Please sign in to comment.