Cross-origin Presentation view not detecting "Documents on this page

5 replies
Last updated: Dec 6, 2023
Is it currently possible to have the new Presentation view load the appropriate "Documents on this page" when the studio is cross origin? I'm using next.js and developing within local environment only so far, on ports :3000 for next and :3333 for studio. I seem to be able to link from a Document within Structure and view it in Presentation, it loads correctly. But when loading the Presentation directly it doesn't seem to map back the other way, i.e. it cant find any matching documents.
AI Update

Yes, the Presentation tool's "Documents on this page" feature should work in cross-origin setups like yours (Studio on :3333, Next.js on :3000). The key is proper configuration and understanding how the system detects documents.

Here's what you need to ensure is set up:

In your Studio configuration (sanity.config.ts):

Make sure you've configured allowOrigins in the Presentation tool config:

presentationTool({
  previewUrl: {
    initial: 'http://localhost:3000',
    previewMode: {
      enable: '/api/draft-mode/enable',
      disable: '/api/draft-mode/disable',
    },
  },
  allowOrigins: ['http://localhost:*'], // This allows any localhost port
})

In your Next.js app:

The "Documents on this page" sidebar is populated through stega-encoded Content Source Maps that are embedded in your server-rendered HTML. This means:

  1. Server-side fetching with stega is sufficient - You don't need client-side loaders for the basic "Documents on this page" functionality to work. The Studio reads the stega-encoded metadata from your rendered DOM.

  2. Make sure you're fetching with stega encoding enabled in your draft mode:

import { client } from '@/sanity/lib/client'

// In your draft mode pages
const data = await client.fetch(query, params, {
  perspective: 'previewDrafts',
  stega: true, // This enables stega encoding
  // or use resultSourceMap: true for the raw source maps
})
  1. Add the VisualEditing component to your preview pages:
import { VisualEditing } from '@sanity/visual-editing'

// In your layout or page when draft mode is active
{draftMode().isEnabled && <VisualEditing />}

Troubleshooting your specific issue:

Since clicking from Structure → Presentation works but loading Presentation directly doesn't show documents, check:

  1. CORS settings: Ensure http://localhost:3000 is in your project's CORS origins (manage.sanity.io → API settings)

  2. Draft mode activation: When you load Presentation directly, is your Next.js app actually entering draft mode? The Presentation tool should be calling your /api/draft-mode/enable endpoint.

  3. Stega encoding: Verify stega is enabled in your data fetching. You can inspect the DOM and look for invisible Unicode characters appended to text content (these contain the document references).

The system works cross-origin by reading the stega-encoded metadata directly from your rendered HTML - no postMessage communication is required for basic "Documents on this page" functionality. Client-side loaders (like useQuery) are only needed for enhanced features like near-instant refresh rates and drag-and-drop page building.

Show original thread
5 replies
In other words, where is the logic that takes the current url in the presentation view, and triggers the studio to pull related documents in the side bar?
Digging through docs and source code, I cant find anything that explains how this is supposed to work.
Update - finally figured out that the "optional" useQuery hook is what connects the two, I think it would be great to document that the useQuery hook actually does more than just load live client-side data, but also facilitates that connection to list the related documents in the studio.
Thanks for this
user D
- we're currently improving the documentation and making some pretty good simplifications to the API surface. Much appreciated.
cc
user Y
Good signal
user D
!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?