Andre Clark
Front-end Engineer
Andre is located at Spokane, Washington, United States
Visit Andre Clark's profile
Manage Meta tags, openGraph, and locale Data for your site within Sanity Studio
import { openGraph } from "../objects";
export default {
type: "document",
name: "siteMeta",
title: "Site Configuration",
fieldsets: [
{ name: "google", title: "Google Analytics" },
],
groups: [
{
name: "meta",
title: "Site Info",
default: true
},
{
name: "og",
title: "Social Share Info",
},
{
name: "manifest",
title: "Web App Settings",
hidden: ({ document }: { document: {
[key: string]: never;
}}): boolean => !(document.isPwa)
},
{
name: "google",
title: "Google Config",
hidden: ({ document }: { document: {
[key: string]: never;
}}): boolean => !(document.isGoogleAnalyticsEnabled)
},
],
fields: [
{
type: 'string',
name: 'site_name',
title: 'Site Name',
group: ['og', 'meta'],
// fieldset: "optional"
},
{
type: "text",
name: "ogDescription",
title: "Social Share Description",
group: ['og', 'meta']
},
{
type: 'url',
title: 'URL',
name: 'url',
description: 'Most likely either the url of the page or its canonical url',
validation: (Rule: Rule) => Rule.required(),
group: ['og', 'meta'],
// fieldset: "basic"
},
{
type: 'string',
title: 'Page Title',
name: 'ogTitle',
description:
'Set the title Open Graph should use. In most situations, this should be different from the value of the title prop',
validation: (Rule: Rule) => Rule.required(),
// fieldset: "basic"
},
{
type: 'image',
title: 'Image',
name: 'ogImage',
description:
'URL of the image that should be used in social media previews. If you define this, you must define two other OG basic properties as well: title and type.',
validation: (Rule: Rule) => Rule.required(),
group: ['og'],
// fieldset: "basic"
},
{
type: "text",
name: "description",
title: "Describe This Site",
group: ["meta", "og"]
},
{
type: "boolean",
name: "isPwa",
title: "should this site be installable like an app?",
group: [
"meta", "manifest"
],
initialValue: false,
options: {
layout: "checkbox"
}
},
{
type: "boolean",
name: "isGoogleAnalyticsEnabled",
title: "Enable Google Analytics?",
group: ["meta", "google"],
initialValue: false,
options: {
layout: "checkbox"
}
},
{
type: "string",
name: "googleanalyticsId",
title: "Google Analytics ID",
fieldset: "google",
group: ["meta", "google"],
},
{
type: "string",
name: "googleSiteVerificationId",
title: "Google site Verification ID",
fieldset: "google",
group: ["meta", "google"],
},
{
type: "manifest",
title: "Web App Features",
name: "manifest",
group: "manifest"
}
],
initialValue: {
isPwa: false,
isGoogleAnalyticsEnabled: false,
}
};
import type { Rule } from "@sanity/types";
import locale from "./locale";
export default {
name: "openGraph",
title: "Social Share Config",
type: "object",
fields: [
{
type: 'string',
name: 'site_name',
title: 'Site Name',
group: ['og', 'meta'],
// fieldset: "optional"
},
{
type: "text",
name: "ogDescription",
title: "Social Share Description",
group: ['og', 'meta']
},
{
type: 'url',
title: 'URL',
name: 'url',
description: 'Most likely either the url of the page or its canonical url',
validation: (Rule: Rule) => Rule.required(),
group: ['og', 'meta'],
// fieldset: "basic"
},
{
type: 'string',
title: 'Page Title',
name: 'ogTitle',
description:
'Set the title Open Graph should use. In most situations, this should be different from the value of the title prop',
validation: (Rule: Rule) => Rule.required(),
// fieldset: "basic"
},
{
type: 'image',
title: 'Image',
name: 'ogImage',
description:
'URL of the image that should be used in social media previews. If you define this, you must define two other OG basic properties as well: title and type.',
validation: (Rule: Rule) => Rule.required(),
group: ['og'],
// fieldset: "basic"
},
locale
]
}
const LOCALES: Locales = [
{
title: "American English",
value: "en-US",
},
{
title: "British English",
value: "en-GB",
},
{
title: "French",
value: "fr-FR",
},
];
const DISPLAYMODES: DisplayModes = [
'browser',
'fullscreen',
'minimal-ui',
'standalone',
]
export default {
type: "string",
name: "locale",
title: "Language",
description:
"used for informing the browser the site's language. Should be a valid bcp47 language code like en, 'en-US', 'no' or 'nb-NO'",
options: {
list: LOCALES
},
initialValue: LOCALES[0].value,
group: ['meta', 'og'],
}
const querySiteMeta = `
*[_type=="siteMeta"][0] {
title,
description,
"canonical": url,
isGoogleAnalyticsEnabled,
isPwa,
manifest {
...,
"background_color": background_color.hex,
"theme_color": theme_color.hex
},
"openGraph": {
"basic": {
title,
url,
"image": image.asset->url
},
"optional": {
locale,
site_name,
description
}
}
}
`
export default async function getSiteMeta(
query: string = querySiteMeta,
client: SanityClientLike,
mutation = "fetch"
):Promise<Site> {
const site: Site = await client[mutation](query)
return site
}
siteMeta.ts
is ideally used as a singleton document within the settings/configuration section of your studio.openGraph.ts
and locale.ts
can also be imported as individual objects/ fields to add anywhere into your schemas.
the siteMeta document can be fetched/queried with getSiteMeta.ts
the function also includes the groq query.
also available as a packagenpm i sanity-meta
improvements and contributions welcome
github repository: https://github.com/AndreBClark/cosmic-schemas/tree/main/schemas/sanity-meta
Front-end Engineer