Skip to content

Instantly share code, notes, and snippets.

@PetterRuud
Created June 7, 2021 20:38
Show Gist options
  • Save PetterRuud/e9e279d40f85fc21f15605bb4c53ebf8 to your computer and use it in GitHub Desktop.
Save PetterRuud/e9e279d40f85fc21f15605bb4c53ebf8 to your computer and use it in GitHub Desktop.
Sanity Studio Preview
const schema = {
AUTHOR: 'author',
ARTICLE: 'article',
DEPARTMENT: 'department',
PAGE: 'page',
SITE_SETTINGS: 'siteSettings',
REDIRECT: 'redirect',
SEO_SETTINGS: 'seoSettings',
SOCIAL_MEDIA_SETTINGS: 'socialMediaSettings',
MEDIA_TAG: 'media.tag',
HOME_PAGE: 'homePage',
};
type Props = {
schemaType: {
name: string;
};
displayed: {
slug?: {
current: string;
};
};
options: {
previewURL?: string;
};
};
export const getPreviewUrl = ({ schemaType, displayed, options = {} }: Props) => {
const projectUrl = process.env.NODE_ENV === 'production' ? `../../` : `http://localhost:3000/`;
const previewSecret = 'MARIUS_ROED';
if (schemaType.name === schema.HOME_PAGE) {
return process.env.NODE_ENV === 'production' ? `../../` : `http://localhost:3000/`;
}
const { slug } = displayed;
const { previewURL } = options;
if (!previewURL && !slug) {
// eslint-disable-next-line no-console
console.warn('Missing preview URL', { slug, previewURL });
return false;
}
if (schemaType.name !== schema.HOME_PAGE && !slug?.current) {
// eslint-disable-next-line no-console
console.warn(`The ${schemaType.name} needs a slug before it can be previewed.`);
return false;
}
if (schemaType.name === schema.PAGE) {
return `${projectUrl}api/preview?secret=${previewSecret}&type=${schemaType.name}&slug=${slug?.current}&preview=true`;
}
return `${projectUrl}api/preview?secret=${previewSecret}&type=${schemaType.name}&slug=${slug?.current}&preview=true`;
};
export default getPreviewUrl;
import React, { useState, useEffect } from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import { Select } from '@sanity/ui';
import { PreviewProps } from './types';
import { getPreviewUrl } from './utils';
import styles from './web.css';
/**
* This preview component assumes the path is .../<_type>/[slug] where category is the plural of schemaType.name
* Examples:
* (1)The author 'Linda Aas' can be previewed at .../authors/linda-aas
* (2)The article 'wind energy' can be previewed at .../articles/wind-enery
*/
type DeviceType = 'desktop' | 'mobile';
const devices = {
desktop: { width: '100%' },
mobile: { width: '468px' },
};
const previewLoadingDelay = 1500;
export function PreviewWeb({ schemaType, document, options }: PreviewProps) {
const [device, setDevice] = useState<string>('desktop');
const [url, setUrl] = useState<string | boolean>(false);
useEffect(() => {
const { displayed } = document;
const timer1 = setTimeout(
() => setUrl(getPreviewUrl({ schemaType, displayed, options })),
previewLoadingDelay,
);
return () => {
clearTimeout(timer1);
};
}, [options, schemaType, document]);
if (!url) {
return 'Loading';
}
const { width } = devices[device as DeviceType];
return (
<div className={styles.wrapper}>
<div className={styles.select}>
<Select onChange={(event) => setDevice(event.currentTarget.value)}>
<option value="desktop">Web</option>
<option value="mobile">Mobile</option>
</Select>
</div>
<div className={styles.iframeContainer}>
<iframe src={`${url}`} frameBorder="0" title="preview iframe" style={{ width }} />
</div>
</div>
);
}
PreviewWeb.defaultProps = {
options: null,
};
export default PreviewWeb;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment