Intitial commit

This commit is contained in:
Henrik Larsson
2023-08-18 15:31:44 +02:00
parent 4245628da1
commit f8183a5a69
13 changed files with 268 additions and 141 deletions

33
lib/sanity/sanity.api.ts Normal file
View File

@@ -0,0 +1,33 @@
/**
* As this file is reused in several other files, try to keep it lean and small.
* Importing other npm packages here could lead to needlessly increasing the client bundle size, or end up in a server-only function that don't need it.
*/
export const dataset = assertValue(
process.env.NEXT_PUBLIC_SANITY_DATASET,
'Missing environment variable: NEXT_PUBLIC_SANITY_DATASET',
)
export const projectId = assertValue(
process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
'Missing environment variable: NEXT_PUBLIC_SANITY_PROJECT_ID',
)
// see https://www.sanity.io/docs/api-versioning for how versioning works
export const apiVersion =
process.env.NEXT_PUBLIC_SANITY_API_VERSION || '2023-06-21'
// This is the document id used for the preview secret that's stored in your dataset.
// The secret protects against unauthorized access to your draft content and have a lifetime of 60 minutes, to protect against bruteforcing.
export const previewSecretId: `${string}.${string}` = 'preview.secret'
// See the app/api/revalidate/route.ts for how this is used
export const revalidateSecret = process.env.SANITY_REVALIDATE_SECRET
function assertValue<T>(v: T | undefined, errorMessage: string): T {
if (v === undefined) {
throw new Error(errorMessage)
}
return v
}

View File

@@ -1,31 +1,16 @@
import type { SanityClient } from "@sanity/client";
import { createClient } from "@sanity/client";
import { cache } from "react";
import { createClient } from 'next-sanity'
import {
apiVersion,
dataset,
projectId,
revalidateSecret,
} from './sanity.api'
export function getClient(preview?: {token?: string}): SanityClient {
const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
apiVersion: process.env.NEXT_PUBLIC_SANITY_API_VERSION,
useCdn: true,
perspective: 'published',
})
if (preview) {
if (!preview.token) {
throw new Error('You must provide a token to preview drafts')
}
return client.withConfig({
token: preview.token,
useCdn: false,
ignoreBrowserTokenWarning: true,
perspective: 'previewDrafts',
})
}
return client
}
export const getCachedClient = (preview?: {token?: string}) => {
const client = getClient(preview);
return cache(client.fetch.bind(client));
};
export const client = createClient({
projectId,
dataset,
apiVersion,
// If webhook revalidation is setup we want the freshest content, if not then it's best to use the speedy CDN
useCdn: revalidateSecret ? false : true,
perspective: 'published',
})

View File

@@ -0,0 +1,61 @@
import 'server-only'
import type { QueryParams } from '@sanity/client'
import { client } from './sanity.client'
import { draftMode } from 'next/headers'
import { revalidateSecret } from './sanity.api'
import { homePageQuery } from './queries'
import { HomePagePayload } from './sanity.types'
export const token = process.env.SANITY_API_READ_TOKEN
const DEFAULT_PARAMS = {} as QueryParams
const DEFAULT_TAGS = [] as string[]
export async function sanityFetch<QueryResponse>({
query,
params = DEFAULT_PARAMS,
tags = DEFAULT_TAGS,
}: {
query: string
params?: QueryParams
tags: string[]
}): Promise<QueryResponse> {
const isDraftMode = draftMode().isEnabled
if (isDraftMode && !token) {
throw new Error(
'The `SANITY_API_READ_TOKEN` environment variable is required.',
)
}
// @TODO this won't be necessary after https://github.com/sanity-io/client/pull/299 lands
const sanityClient =
client.config().useCdn && isDraftMode
? client.withConfig({ useCdn: false })
: client
return sanityClient.fetch<QueryResponse>(query, params, {
// We only cache if there's a revalidation webhook setup
cache: revalidateSecret ? 'force-cache' : 'no-store',
...(isDraftMode && {
cache: undefined,
token: token,
perspective: 'previewDrafts',
}),
next: {
...(isDraftMode && { revalidate: 30 }),
tags,
},
})
}
export function getHomePage(locale: string) {
return sanityFetch<HomePagePayload | null>({
query: homePageQuery,
params: { locale },
tags: ['home', 'products', 'categories'],
})
}

View File

@@ -1,7 +1,10 @@
import createImageUrlBuilder from '@sanity/image-url'
import { getClient } from './sanity.client'
import { dataset, projectId } from './sanity.api'
export const imageBuilder = createImageUrlBuilder(getClient())
const imageBuilder = createImageUrlBuilder({
projectId: projectId || '',
dataset: dataset || '',
})
export const urlForImage = (source: any) =>
imageBuilder.image(source).auto('format').fit('crop')

View File

@@ -0,0 +1,12 @@
import type { Image } from 'sanity'
export interface HomePagePayload {
content?: []
title?: string
_type?: string
seo?: {
title?: string;
description?: string;
image: Image
}
}