mirror of
https://github.com/vercel/commerce.git
synced 2025-05-19 16:07:01 +00:00
Intitial commit
This commit is contained in:
parent
4245628da1
commit
f8183a5a69
@ -1,9 +1,9 @@
|
|||||||
import HomePage from '@/components/pages/home-page';
|
import HomePage from '@/components/pages/home-page';
|
||||||
import HomePagePreview from '@/components/pages/home-page-preview';
|
import HomePagePreview from '@/components/pages/home-page-preview';
|
||||||
import PreviewProvider from '@/components/preview-provider';
|
import { homePageQuery } from '@/lib/sanity/queries';
|
||||||
import { homePageQuery } from 'lib/sanity/queries';
|
import { getHomePage } from '@/lib/sanity/sanity.fetch';
|
||||||
import { getCachedClient } from 'lib/sanity/sanity.client';
|
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
|
import { LiveQuery } from 'next-sanity/preview/live-query';
|
||||||
import { draftMode } from 'next/headers';
|
import { draftMode } from 'next/headers';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
@ -13,15 +13,15 @@ export const dynamic = 'force-dynamic';
|
|||||||
export async function generateMetadata({
|
export async function generateMetadata({
|
||||||
params
|
params
|
||||||
}: {
|
}: {
|
||||||
params: { slug: string; locale: string };
|
params: { locale: string };
|
||||||
}): Promise<Metadata> {
|
}): Promise<Metadata> {
|
||||||
const homePage = await getCachedClient()(homePageQuery, params);
|
const homePage = await getHomePage(params.locale);
|
||||||
|
|
||||||
if (!homePage) return notFound();
|
if (!homePage) return notFound();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: homePage.seo.title || homePage.title,
|
title: homePage?.seo?.title || homePage.title,
|
||||||
description: homePage.seo.description || homePage.description
|
description: homePage?.seo?.description
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
interface HomePageParams {
|
interface HomePageParams {
|
||||||
@ -31,19 +31,22 @@ interface HomePageParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function IndexPage({ params }: HomePageParams) {
|
export default async function IndexPage({ params }: HomePageParams) {
|
||||||
const preview = draftMode().isEnabled ? { token: process.env.SANITY_API_READ_TOKEN } : undefined;
|
// const preview = draftMode().isEnabled ? { token: process.env.SANITY_API_READ_TOKEN } : undefined;
|
||||||
|
|
||||||
const data = await getCachedClient(preview)(homePageQuery, params);
|
const data = await getHomePage(params.locale);
|
||||||
|
|
||||||
if (!data) return notFound();
|
if (!data && !draftMode().isEnabled) {
|
||||||
|
notFound();
|
||||||
if (preview && preview.token) {
|
|
||||||
return (
|
|
||||||
<PreviewProvider token={preview.token}>
|
|
||||||
<HomePagePreview initialData={data} params={params} />
|
|
||||||
</PreviewProvider>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <HomePage data={data} />;
|
return (
|
||||||
|
<LiveQuery
|
||||||
|
enabled={draftMode().isEnabled}
|
||||||
|
query={homePageQuery}
|
||||||
|
initialData={data}
|
||||||
|
as={HomePagePreview}
|
||||||
|
>
|
||||||
|
<HomePage data={data} />
|
||||||
|
</LiveQuery>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import Text from '@/components/ui/text';
|
// import { footerMenusQuery } from '@/lib/sanity/queries';
|
||||||
import { footerMenusQuery } from '@/lib/sanity/queries';
|
// import { getCachedClient } from '@/lib/sanity/sanity.client';
|
||||||
import { getCachedClient } from '@/lib/sanity/sanity.client';
|
|
||||||
import LocaleSwitcher from 'components/ui/locale-switcher/locale-switcher';
|
import LocaleSwitcher from 'components/ui/locale-switcher/locale-switcher';
|
||||||
import Logo from 'components/ui/logo/logo';
|
import Logo from 'components/ui/logo/logo';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
@ -15,7 +14,7 @@ export default async function Footer({ locale }: FooterProps) {
|
|||||||
locale: locale
|
locale: locale
|
||||||
};
|
};
|
||||||
|
|
||||||
const footerMenus = await getCachedClient()(footerMenusQuery, params);
|
// const footerMenus = await getCachedClient()(footerMenusQuery, params);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="border-t border-ui-border bg-app">
|
<footer className="border-t border-ui-border bg-app">
|
||||||
@ -27,7 +26,7 @@ export default async function Footer({ locale }: FooterProps) {
|
|||||||
<LocaleSwitcher />
|
<LocaleSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{footerMenus.length > 0 && (
|
{/* {footerMenus.length > 0 && (
|
||||||
<div className="grid w-full grid-cols-2 gap-4 p-4 lg:grid-cols-4 lg:gap-8 lg:px-8 lg:py-6 2xl:px-16 2xl:py-8">
|
<div className="grid w-full grid-cols-2 gap-4 p-4 lg:grid-cols-4 lg:gap-8 lg:px-8 lg:py-6 2xl:px-16 2xl:py-8">
|
||||||
{footerMenus.map((menu: object | any, index: number) => {
|
{footerMenus.map((menu: object | any, index: number) => {
|
||||||
return (
|
return (
|
||||||
@ -61,7 +60,7 @@ export default async function Footer({ locale }: FooterProps) {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)} */}
|
||||||
|
|
||||||
<div className="flex items-center justify-center border-t border-ui-border bg-black px-4 py-3 lg:px-8 2xl:px-16">
|
<div className="flex items-center justify-center border-t border-ui-border bg-black px-4 py-3 lg:px-8 2xl:px-16">
|
||||||
<CopyRight />
|
<CopyRight />
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import { categoriesQuery } from '@/lib/sanity/queries';
|
|
||||||
import { getCachedClient } from '@/lib/sanity/sanity.client';
|
|
||||||
import Cart from 'components/cart';
|
import Cart from 'components/cart';
|
||||||
import OpenCart from 'components/cart/open-cart';
|
import OpenCart from 'components/cart/open-cart';
|
||||||
import Logo from 'components/ui/logo/logo';
|
import Logo from 'components/ui/logo/logo';
|
||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import DesktopMenu from './desktop-menu/desktop-menu';
|
|
||||||
import HeaderRoot from './header-root';
|
import HeaderRoot from './header-root';
|
||||||
import MobileMenuModal from './mobile-menu/modal';
|
|
||||||
import OpenMobileMenu from './mobile-menu/open-mobile-menu';
|
import OpenMobileMenu from './mobile-menu/open-mobile-menu';
|
||||||
import SearchModal from './search/modal';
|
import SearchModal from './search/modal';
|
||||||
import OpenSearch from './search/open-search';
|
import OpenSearch from './search/open-search';
|
||||||
@ -18,10 +14,10 @@ interface HeaderProps {
|
|||||||
locale: string;
|
locale: string;
|
||||||
}
|
}
|
||||||
export default async function Header({ locale }: HeaderProps) {
|
export default async function Header({ locale }: HeaderProps) {
|
||||||
const params = {
|
// const params = {
|
||||||
locale: locale
|
// locale: locale
|
||||||
};
|
// };
|
||||||
const mainMenu = await getCachedClient()(categoriesQuery, params);
|
// const mainMenu = await getCachedClient()(categoriesQuery, params);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderRoot>
|
<HeaderRoot>
|
||||||
@ -29,7 +25,7 @@ export default async function Header({ locale }: HeaderProps) {
|
|||||||
<div className="relative flex w-full items-center justify-between px-4 py-2 lg:px-8 2xl:px-16">
|
<div className="relative flex w-full items-center justify-between px-4 py-2 lg:px-8 2xl:px-16">
|
||||||
<div className="-translate-x-2 transform md:hidden">
|
<div className="-translate-x-2 transform md:hidden">
|
||||||
<Suspense fallback={<OpenMobileMenu />}>
|
<Suspense fallback={<OpenMobileMenu />}>
|
||||||
<MobileMenuModal items={mainMenu} />
|
{/* <MobileMenuModal items={mainMenu} /> */}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -44,9 +40,7 @@ export default async function Header({ locale }: HeaderProps) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="absolute left-1/2 top-1/2 hidden -translate-x-1/2 -translate-y-1/2 transform md:flex">
|
<div className="absolute left-1/2 top-1/2 hidden -translate-x-1/2 -translate-y-1/2 transform md:flex">
|
||||||
<Suspense>
|
<Suspense>{/* <DesktopMenu items={mainMenu} /> */}</Suspense>
|
||||||
<DesktopMenu items={mainMenu} />
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex translate-x-2 transform justify-end space-x-1">
|
<div className="flex translate-x-2 transform justify-end space-x-1">
|
||||||
<Suspense fallback={<OpenSearch />}>
|
<Suspense fallback={<OpenSearch />}>
|
||||||
|
@ -7,7 +7,7 @@ interface HeroProps {
|
|||||||
text?: string;
|
text?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
title: string;
|
title: string;
|
||||||
image: object | any;
|
image?: { asset?: any };
|
||||||
color?: string;
|
color?: string;
|
||||||
overlay?: boolean;
|
overlay?: boolean;
|
||||||
link: {
|
link: {
|
||||||
@ -31,6 +31,8 @@ const heroSize = {
|
|||||||
const Hero = ({ variant, title, text, label, image, link, color, overlay }: HeroProps) => {
|
const Hero = ({ variant, title, text, label, image, link, color, overlay }: HeroProps) => {
|
||||||
const heroClass = heroSize[variant as HeroSize] || heroSize.fullScreen;
|
const heroClass = heroSize[variant as HeroSize] || heroSize.fullScreen;
|
||||||
|
|
||||||
|
console.log(image);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative w-screen ${heroClass} relative flex flex-col justify-end bg-neutral-300 text-high-contrast`}
|
className={`relative w-screen ${heroClass} relative flex flex-col justify-end bg-neutral-300 text-high-contrast`}
|
||||||
@ -38,10 +40,9 @@ const Hero = ({ variant, title, text, label, image, link, color, overlay }: Hero
|
|||||||
{image && (
|
{image && (
|
||||||
<SanityImage
|
<SanityImage
|
||||||
image={image}
|
image={image}
|
||||||
alt={image.alt}
|
|
||||||
priority={true}
|
priority={true}
|
||||||
className="absolute inset-0 z-10 h-full w-full object-cover"
|
className="absolute inset-0 z-10 h-full w-full object-cover"
|
||||||
sizes="100vw"
|
size="100vw"
|
||||||
fill
|
fill
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import DynamicContentManager from '@/components/layout/dynamic-content-manager/dynamic-content-manager';
|
import DynamicContentManager from '@/components/layout/dynamic-content-manager/dynamic-content-manager';
|
||||||
|
import type { HomePagePayload } from '@/lib/sanity/sanity.types';
|
||||||
interface IndexPageParams {
|
interface IndexPageParams {
|
||||||
data: object | any;
|
data: HomePagePayload | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HomePage({ data }: IndexPageParams) {
|
export default function HomePage({ data }: IndexPageParams) {
|
||||||
|
// console.log(data);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DynamicContentManager content={data?.content} />;
|
<DynamicContentManager content={data?.content} />;
|
||||||
|
@ -1,78 +1,112 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { urlForImage } from 'lib/sanity/sanity.image';
|
import { urlForImage } from 'lib/sanity/sanity.image';
|
||||||
import { cn } from 'lib/utils';
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
interface SanityImageProps {
|
interface SanityImageProps {
|
||||||
image: object | any;
|
image: object | any;
|
||||||
alt: string;
|
alt?: string;
|
||||||
priority?: boolean;
|
priority?: boolean;
|
||||||
width?: number;
|
width?: number;
|
||||||
height?: number;
|
height?: number;
|
||||||
quality?: number;
|
size?: string;
|
||||||
sizes?: string;
|
|
||||||
className?: string;
|
className?: string;
|
||||||
fill?: boolean;
|
fill?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const placeholderImg = '/product-img-placeholder.svg';
|
// const placeholderImg = '/product-img-placeholder.svg';
|
||||||
|
|
||||||
export default function SanityImage(props: SanityImageProps) {
|
export default function SanityImage({
|
||||||
const {
|
image,
|
||||||
image: source,
|
alt = 'Cover image',
|
||||||
priority = false,
|
width = 3500,
|
||||||
quality = 75,
|
height = 2000,
|
||||||
alt = '',
|
size = '100vw',
|
||||||
height = 1080,
|
fill = false,
|
||||||
width = 1080,
|
className
|
||||||
sizes = '100vw',
|
}: SanityImageProps) {
|
||||||
className,
|
const imageUrl = image && urlForImage(image)?.height(height).width(width).fit('crop').url();
|
||||||
fill = false
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const rootClassName = cn('w-full h-auto', className);
|
console.log(imageUrl);
|
||||||
|
|
||||||
const image = source?.asset?._rev ? (
|
return (
|
||||||
<>
|
<div className={`w-full overflow-hidden rounded-[3px] bg-gray-50 ${className}`}>
|
||||||
{fill ? (
|
{fill && imageUrl && (
|
||||||
<Image
|
<Image
|
||||||
className={`${rootClassName}`}
|
fill={fill}
|
||||||
placeholder="blur"
|
className="absolute h-full w-full object-cover"
|
||||||
fill
|
alt={alt ? alt : ''}
|
||||||
alt={alt}
|
sizes={size}
|
||||||
src={urlForImage(source).quality(quality).url()}
|
src={imageUrl}
|
||||||
sizes={sizes}
|
|
||||||
priority={priority}
|
|
||||||
blurDataURL={source.asset.metadata.lqip}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Image
|
|
||||||
className={`${rootClassName}`}
|
|
||||||
placeholder="blur"
|
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
alt={alt}
|
|
||||||
src={urlForImage(source).width(width).height(height).quality(quality).url()}
|
|
||||||
sizes={sizes}
|
|
||||||
priority={priority}
|
|
||||||
blurDataURL={source.asset.metadata.lqip}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Image
|
|
||||||
className={`${rootClassName}`}
|
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
alt={alt}
|
|
||||||
src={placeholderImg}
|
|
||||||
sizes={sizes}
|
|
||||||
priority={false}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
return image;
|
{imageUrl && (
|
||||||
|
<Image
|
||||||
|
className="absolute h-full w-full object-cover"
|
||||||
|
alt={alt ? alt : ''}
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
sizes={size}
|
||||||
|
src={imageUrl}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// export default function SanityImage(props: SanityImageProps) {
|
||||||
|
// const {
|
||||||
|
// image: source,
|
||||||
|
// priority = false,
|
||||||
|
// alt = '',
|
||||||
|
// height = 1080,
|
||||||
|
// width = 1080,
|
||||||
|
// sizes = '100vw',
|
||||||
|
// className,
|
||||||
|
// fill = false
|
||||||
|
// } = props;
|
||||||
|
|
||||||
|
// const rootClassName = cn('w-full h-auto', className);
|
||||||
|
|
||||||
|
// const image = source?.asset ? (
|
||||||
|
// <>
|
||||||
|
// {fill ? (
|
||||||
|
// <Image
|
||||||
|
// className={`${rootClassName}`}
|
||||||
|
// placeholder="blur"
|
||||||
|
// fill
|
||||||
|
// alt={alt}
|
||||||
|
// src={urlForImage(source).url()}
|
||||||
|
// sizes={sizes}
|
||||||
|
// priority={priority}
|
||||||
|
// blurDataURL={source.asset.metadata.lqip}
|
||||||
|
// />
|
||||||
|
// ) : (
|
||||||
|
// <Image
|
||||||
|
// className={`${rootClassName}`}
|
||||||
|
// placeholder="blur"
|
||||||
|
// width={width}
|
||||||
|
// height={height}
|
||||||
|
// alt={alt}
|
||||||
|
// src={urlForImage(source).width(width).height(height).url()}
|
||||||
|
// sizes={sizes}
|
||||||
|
// priority={priority}
|
||||||
|
// blurDataURL={source.asset.metadata.lqip}
|
||||||
|
// />
|
||||||
|
// )}
|
||||||
|
// </>
|
||||||
|
// ) : (
|
||||||
|
// <>
|
||||||
|
// <Image
|
||||||
|
// className={`${rootClassName}`}
|
||||||
|
// width={width}
|
||||||
|
// height={height}
|
||||||
|
// alt={alt}
|
||||||
|
// src={placeholderImg}
|
||||||
|
// sizes={sizes}
|
||||||
|
// priority={false}
|
||||||
|
// />
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
|
||||||
|
// return image;
|
||||||
|
// }
|
||||||
|
33
lib/sanity/sanity.api.ts
Normal file
33
lib/sanity/sanity.api.ts
Normal 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
|
||||||
|
}
|
@ -1,31 +1,16 @@
|
|||||||
import type { SanityClient } from "@sanity/client";
|
import { createClient } from 'next-sanity'
|
||||||
import { createClient } from "@sanity/client";
|
import {
|
||||||
import { cache } from "react";
|
apiVersion,
|
||||||
|
dataset,
|
||||||
|
projectId,
|
||||||
|
revalidateSecret,
|
||||||
|
} from './sanity.api'
|
||||||
|
|
||||||
export function getClient(preview?: {token?: string}): SanityClient {
|
export const client = createClient({
|
||||||
const client = createClient({
|
projectId,
|
||||||
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
|
dataset,
|
||||||
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
|
apiVersion,
|
||||||
apiVersion: process.env.NEXT_PUBLIC_SANITY_API_VERSION,
|
// If webhook revalidation is setup we want the freshest content, if not then it's best to use the speedy CDN
|
||||||
useCdn: true,
|
useCdn: revalidateSecret ? false : true,
|
||||||
perspective: 'published',
|
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));
|
|
||||||
};
|
|
61
lib/sanity/sanity.fetch.ts
Normal file
61
lib/sanity/sanity.fetch.ts
Normal 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'],
|
||||||
|
})
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
import createImageUrlBuilder from '@sanity/image-url'
|
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) =>
|
export const urlForImage = (source: any) =>
|
||||||
imageBuilder.image(source).auto('format').fit('crop')
|
imageBuilder.image(source).auto('format').fit('crop')
|
||||||
|
12
lib/sanity/sanity.types.ts
Normal file
12
lib/sanity/sanity.types.ts
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -44,7 +44,7 @@
|
|||||||
"is-empty-iterable": "^3.0.0",
|
"is-empty-iterable": "^3.0.0",
|
||||||
"next": "13.4.13",
|
"next": "13.4.13",
|
||||||
"next-intl": "2.19.1",
|
"next-intl": "2.19.1",
|
||||||
"next-sanity": "^5.3.0",
|
"next-sanity": "^5.4.2",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-cookie": "^4.1.1",
|
"react-cookie": "^4.1.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@ -81,8 +81,8 @@ dependencies:
|
|||||||
specifier: 2.19.1
|
specifier: 2.19.1
|
||||||
version: 2.19.1(next@13.4.13)(react@18.2.0)
|
version: 2.19.1(next@13.4.13)(react@18.2.0)
|
||||||
next-sanity:
|
next-sanity:
|
||||||
specifier: ^5.3.0
|
specifier: ^5.4.2
|
||||||
version: 5.3.0(@sanity/client@6.4.4)(@sanity/icons@2.4.1)(@sanity/types@3.15.0)(@sanity/ui@1.7.4)(@types/styled-components@5.1.26)(next@13.4.13)(react@18.2.0)(sanity@3.15.0)(styled-components@5.3.11)
|
version: 5.4.2(@sanity/client@6.4.4)(@sanity/icons@2.4.1)(@sanity/types@3.15.0)(@sanity/ui@1.7.4)(@types/styled-components@5.1.26)(next@13.4.13)(react@18.2.0)(sanity@3.15.0)(styled-components@5.3.11)
|
||||||
react:
|
react:
|
||||||
specifier: 18.2.0
|
specifier: 18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
@ -2409,11 +2409,11 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@sanity/preview-kit@3.0.0(@sanity/client@6.4.4)(react@18.2.0):
|
/@sanity/preview-kit@3.1.3(@sanity/client@6.4.4)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-LF83FQJ0kZgB8Dz8nolseiXh+AsX0UaNd3GhNLMrsmSjy6GCagNyQzCpadysQyuBZHftXgMN/fQ0/gfoMjNSDA==}
|
resolution: {integrity: sha512-v8zqm4uxE42RXmYySrULfscvdIFPjLwIrBbhRb+qumZNdGkTZph3y0Zo9rdW9MnOEYwew0pz6BUq+n7y/NoRwA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@sanity/client': ^6.4.6
|
'@sanity/client': ^6.4.8
|
||||||
react: ^18.0.0
|
react: ^18.0.0
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
react:
|
react:
|
||||||
@ -6101,11 +6101,11 @@ packages:
|
|||||||
use-intl: 2.19.1(react@18.2.0)
|
use-intl: 2.19.1(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/next-sanity@5.3.0(@sanity/client@6.4.4)(@sanity/icons@2.4.1)(@sanity/types@3.15.0)(@sanity/ui@1.7.4)(@types/styled-components@5.1.26)(next@13.4.13)(react@18.2.0)(sanity@3.15.0)(styled-components@5.3.11):
|
/next-sanity@5.4.2(@sanity/client@6.4.4)(@sanity/icons@2.4.1)(@sanity/types@3.15.0)(@sanity/ui@1.7.4)(@types/styled-components@5.1.26)(next@13.4.13)(react@18.2.0)(sanity@3.15.0)(styled-components@5.3.11):
|
||||||
resolution: {integrity: sha512-cBeO3QgIjR9UPjDedNfLT4m6vmeFlDn9HAVT/6q8CbMMf+bcpxQ94jpLGGkaPRzoeCy/XWKK4IXNQYDSs4ApIA==}
|
resolution: {integrity: sha512-gLpS0GlapXtDjRUaPcZ9DUeiNSznhtqh0kyxygQS9MDtecCiphVAhXYwvJMQcxfY1u5KVWAxZMyy+Bs6h8G+jA==}
|
||||||
engines: {node: '>=16.14'}
|
engines: {node: '>=16.14'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@sanity/client': ^6.4.6
|
'@sanity/client': ^6.4.8
|
||||||
'@sanity/icons': ^2.0.0
|
'@sanity/icons': ^2.0.0
|
||||||
'@sanity/types': ^3.0.0
|
'@sanity/types': ^3.0.0
|
||||||
'@sanity/ui': ^1.0.0
|
'@sanity/ui': ^1.0.0
|
||||||
@ -6117,7 +6117,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@sanity/client': 6.4.4
|
'@sanity/client': 6.4.4
|
||||||
'@sanity/icons': 2.4.1(react@18.2.0)
|
'@sanity/icons': 2.4.1(react@18.2.0)
|
||||||
'@sanity/preview-kit': 3.0.0(@sanity/client@6.4.4)(react@18.2.0)
|
'@sanity/preview-kit': 3.1.3(@sanity/client@6.4.4)(react@18.2.0)
|
||||||
'@sanity/types': 3.15.0
|
'@sanity/types': 3.15.0
|
||||||
'@sanity/ui': 1.7.4(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)(styled-components@5.3.11)
|
'@sanity/ui': 1.7.4(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)(styled-components@5.3.11)
|
||||||
'@sanity/webhook': 2.0.0
|
'@sanity/webhook': 2.0.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user