sanity
sanity copied to clipboard
production-preview/resolve-production-url - Accept promise
Currently this interface only accepts methods which return a string. Could it accept methods which return a promise please?
+1 on this, and generally more parts accepting promises/observables (such as document action resolver, input type resolver etc)
I need this as well. In the meantime, I have a workaround for anyone else in the same boat via the document actions API.
// sanity.json
{
"parts": [
{
"implements": "part:@sanity/base/document-actions/resolver",
"path": "./resolveDocumentActions"
}
]
}
// resolveDocumentActions.js
import React from 'react';
import { EarthGlobeIcon } from '@sanity/icons';
import defaultResolve from 'part:@sanity/base/document-actions';
import asyncGetLink from '...';
const isPreviewable = document => {
// TODO: implement this function
}
export function OpenPreview({ draft, published }) {
const document = draft || published;
if (!document) {
return null;
}
if (!isPreviewable(document)) {
return null;
}
return {
label: 'Open Preview',
shortcut: 'cmd+shift+o',
icon: () => (
<EarthGlobeIcon
style={{ width: 25, height: 25, transform: 'translateX(-4px)' }}
/>
),
// `onHandle` is where we can sneak in `async`
// 👇
onHandle: async () => {
const link = await asyncGetLink(document);
window.open(link);
},
};
}
export default function resolveDocumentActions(props) {
const [firstDefaultAction, ...restOfDefaultActions] = defaultResolve(props);
return [firstDefaultAction, OpenPreview, ...restOfDefaultActions];
}
It's not the typical place for it but this works for me!
I have a hacky solution to this as well:
I have some document paths that include the slugs of parent sections. Since I can't query for these slugs within the function to resolve the preview URL, i "pre-load" them in the scope of the module:
import client from './client';
let sectionsMap = new Map();
const fetchDocuments = async () => {
const sections = client.fetch(`*[_type == "section"]{ _id, slug }`)
sections.forEach(section => sectionsMap.set(section._id, section.slug.current));
};
/* Run this once on load */
fetchDocuments();
// path: /sections/:sectionSlug/articles/:articleSlug
const resolveArticleUrl = document => {
if (!document.section) return null;
const sectionSlug = sectionsMap.get(document.section._ref);
if (!sectionSlug) return null;
return `${BASE_URL}sections/${sectionSlug}/articles/${document.slug}?preview=${document._id}`;
};
+1
This feature is really needed, when you have dynamic routing based on parent objects such as.
/slug/slug2/slug3, and they are dynamic from parent documents. Allowing resolve-production-url
to be async would fix this.
Giving access only to the "document" does not cut it, because slug or slug2 could be inside a reference. Which you would have to fetch async before resolving it to "slug" or "slug2".
+1 ran into this lately
In the studio we are unaware of the routing that is in the public facing site. So we have an API there to determine the actual url.
+1 on this
wow, why is this not a thing yet? are we missing some other obvious way of solving this issue? I really need to be able to build the preview URL via async queries, otherwise it all needs to be hard-coded, which is very inflexible.
The resolve-production-url API is now async with the release of Sanity Studio v3.