mirror of
https://github.com/vercel/commerce.git
synced 2025-05-14 05:37:51 +00:00
Added preview functionality for home page
This commit is contained in:
parent
31b5f2a8b9
commit
bfdfeeaf97
@ -1,10 +1,10 @@
|
||||
import CategoryPage from '@/components/pages/category-page';
|
||||
import ProductPage from '@/components/pages/product-page';
|
||||
import SinglePage from '@/components/pages/single-page';
|
||||
import getQueryFromSlug from '@/helpers/get-query-from-slug';
|
||||
import { clientFetch } from 'lib/sanity/sanity.client';
|
||||
import { getCachedClient } from 'lib/sanity/sanity.client';
|
||||
import type { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import CategoryPage from './pages/category-page';
|
||||
import ProductPage from './pages/product-page';
|
||||
import SinglePage from './pages/single-page';
|
||||
|
||||
export const revalidate = 43200; // 12 hours in seconds
|
||||
|
||||
@ -17,7 +17,7 @@ export async function generateMetadata({
|
||||
|
||||
const { query = '', queryParams } = getQueryFromSlug(slug, locale);
|
||||
|
||||
const page = await clientFetch(query, queryParams);
|
||||
const page = await getCachedClient()(query, queryParams);
|
||||
|
||||
if (!page) return notFound();
|
||||
|
||||
@ -47,11 +47,11 @@ export default async function Page({ params }: PageParams) {
|
||||
let pageData;
|
||||
|
||||
if (docType === 'page') {
|
||||
pageData = await clientFetch(query, queryParams);
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
} else if (docType === 'product') {
|
||||
pageData = await clientFetch(query, queryParams);
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
} else if (docType === 'category') {
|
||||
pageData = await clientFetch(query, queryParams);
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
import DynamicContentManager from 'components/layout/dynamic-content-manager/dynamic-content-manager';
|
||||
import HomePage from '@/components/pages/home-page';
|
||||
import HomePagePreview from '@/components/pages/home-page-preview';
|
||||
import PreviewProvider from '@/components/preview-provider';
|
||||
import { homePageQuery } from 'lib/sanity/queries';
|
||||
import { clientFetch } from 'lib/sanity/sanity.client';
|
||||
import { getCachedClient } from 'lib/sanity/sanity.client';
|
||||
import { Metadata } from 'next';
|
||||
import { draftMode } from 'next/headers';
|
||||
import { notFound } from 'next/navigation';
|
||||
|
||||
export const runtime = 'edge';
|
||||
|
||||
export async function generateMetadata({
|
||||
params
|
||||
}: {
|
||||
params: { slug: string; locale: string };
|
||||
}): Promise<Metadata> {
|
||||
const homePage = await clientFetch(homePageQuery, params);
|
||||
const homePage = await getCachedClient()(homePageQuery, params);
|
||||
|
||||
if (!homePage) return notFound();
|
||||
|
||||
@ -20,19 +21,26 @@ export async function generateMetadata({
|
||||
description: homePage.seo.description || homePage.description
|
||||
};
|
||||
}
|
||||
|
||||
interface HomePageParams {
|
||||
params: {
|
||||
locale: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default async function HomePage({ params }: HomePageParams) {
|
||||
const data = await clientFetch(homePageQuery, params);
|
||||
export default async function IndexPage({ params }: HomePageParams) {
|
||||
const preview = draftMode().isEnabled ? { token: process.env.SANITY_API_READ_TOKEN } : undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DynamicContentManager content={data?.content} />
|
||||
</>
|
||||
);
|
||||
const data = await getCachedClient(preview)(homePageQuery, params);
|
||||
|
||||
if (!data) return notFound();
|
||||
|
||||
if (preview && preview.token) {
|
||||
return (
|
||||
<PreviewProvider token={preview.token}>
|
||||
<HomePagePreview initialData={data} params={params} />
|
||||
</PreviewProvider>
|
||||
);
|
||||
}
|
||||
|
||||
return <HomePage data={data} />;
|
||||
}
|
||||
|
@ -1,99 +0,0 @@
|
||||
// route handler enabling draft mode
|
||||
import { categoryQuery, homePageQuery, pageQuery, productQuery } from 'lib/sanity/queries';
|
||||
import { client } from 'lib/sanity/sanity.client';
|
||||
import { draftMode } from 'next/headers';
|
||||
|
||||
const draftSecret = process.env.NEXT_PUBLIC_SANITY_DRAFT_TOKEN
|
||||
|
||||
export async function GET(request: Request) {
|
||||
// Enable Draft Mode by setting the cookie
|
||||
draftMode().enable();
|
||||
// Parse query string parameters
|
||||
const { searchParams } = new URL(request.url);
|
||||
const secret = searchParams.get('secret');
|
||||
const slug = searchParams.get('slug');
|
||||
const locale = searchParams.get('locale');
|
||||
const type = searchParams.get('type');
|
||||
|
||||
// Make sure there's a valid draft token.
|
||||
if (secret !== draftSecret) {
|
||||
return new Response('Invalid token', { status: 401 });
|
||||
}
|
||||
|
||||
// Make sure there's a slug provided.
|
||||
if (!slug) {
|
||||
return new Response('No slug provided', { status: 401 });
|
||||
}
|
||||
|
||||
// Make sure there's a locale provided.
|
||||
if (!locale) {
|
||||
return new Response('No locale provided', { status: 401 });
|
||||
}
|
||||
|
||||
// Make sure there's a type provided.
|
||||
if (!type) {
|
||||
return new Response('No type provided', { status: 401 });
|
||||
}
|
||||
|
||||
// Types available for preview - Check if the post with the given `slug` exists
|
||||
const home = await client.fetch(homePageQuery, {
|
||||
slug: slug,
|
||||
locale: locale,
|
||||
})
|
||||
|
||||
const page = await client.fetch(pageQuery, {
|
||||
slug: slug,
|
||||
locale: locale,
|
||||
})
|
||||
|
||||
const product = await client.fetch(productQuery, {
|
||||
slug: slug,
|
||||
locale: locale,
|
||||
})
|
||||
|
||||
const category = await client.fetch(categoryQuery, {
|
||||
slug: slug,
|
||||
locale: locale,
|
||||
})
|
||||
|
||||
|
||||
draftMode().enable();
|
||||
|
||||
// Redirect to the path from the fetched post
|
||||
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
|
||||
if (home && type === 'home') {
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/${home.locale}/${home.slug}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (page && type === 'page') {
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/${page.locale}/${page.slug}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (product && type === 'product') {
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/${product.locale}/product/${product.slug}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (category && type === 'category') {
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/${category.locale}/category/${category.slug}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { draftMode } from 'next/headers';
|
||||
|
||||
export async function GET() {
|
||||
draftMode().disable();
|
||||
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/`,
|
||||
},
|
||||
})
|
||||
}
|
12
app/api/exit-preview/route.ts
Normal file
12
app/api/exit-preview/route.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { draftMode } from "next/headers";
|
||||
|
||||
export async function GET() {
|
||||
draftMode().disable();
|
||||
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/`,
|
||||
},
|
||||
})
|
||||
}
|
27
app/api/preview/route.ts
Normal file
27
app/api/preview/route.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { draftMode } from 'next/headers'
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const secret = searchParams.get('secret')
|
||||
// const slug = searchParams.get('slug')
|
||||
const type = searchParams.get('type')
|
||||
const locale = searchParams.get('locale')
|
||||
|
||||
// Check the secret and next parameters
|
||||
// This secret should only be known to this route handler and the CMS
|
||||
if (secret !== process.env.SANITY_API_READ_TOKEN) {
|
||||
return new Response('Invalid token', { status: 401 })
|
||||
}
|
||||
|
||||
draftMode().enable()
|
||||
|
||||
|
||||
if (type === 'home') {
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
headers: {
|
||||
Location: `/${locale}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
@ -9,81 +9,6 @@ import USPSection from '@/components/modules/usp-section/usp-section';
|
||||
import { InformationCircleIcon } from '@heroicons/react/24/outline';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
// interface getContentComponentProps {
|
||||
// _type: string;
|
||||
// _key: number;
|
||||
// disabled: boolean;
|
||||
// }
|
||||
|
||||
// const getContentComponent = ({ _type, _key, disabled, ...rest }: getContentComponentProps) => {
|
||||
// let Component: any;
|
||||
|
||||
// switch (_type) {
|
||||
// case 'hero':
|
||||
// if (disabled !== true) {
|
||||
// Component = Hero;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// break;
|
||||
// case 'slider':
|
||||
// if (disabled !== true) {
|
||||
// Component = Slider;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// break;
|
||||
// case 'filteredProductList':
|
||||
// if (disabled !== true) {
|
||||
// Component = FilteredProductList;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// break;
|
||||
// case 'blurbSection':
|
||||
// if (disabled !== true) {
|
||||
// Component = BlurbSection;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// break;
|
||||
// case 'uspSection':
|
||||
// if (disabled !== true) {
|
||||
// Component = USPSection;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// break;
|
||||
// case 'reusableSection':
|
||||
// if (disabled !== true) {
|
||||
// Component = ReusableSection;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// break;
|
||||
// default:
|
||||
// return (
|
||||
// <div
|
||||
// className={`px-4 lg:px-8 2xl:px-16 ${
|
||||
// process.env.NODE_ENV === 'production' ? 'hidden' : ''
|
||||
// }`}
|
||||
// key={`index-${_key}`}
|
||||
// >
|
||||
// <span className="inline-flex items-center bg-red p-2 text-sm font-bold">
|
||||
// <InformationCircleIcon className="mr-1" />
|
||||
// {`No matching component (Type: ${_type})`}
|
||||
// </span>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
// return Component ? (
|
||||
// <Component key={`${_key}`} {...rest} />
|
||||
// ) : (
|
||||
// <div key={`${_key}`}>Something else</div>
|
||||
// );
|
||||
// };
|
||||
|
||||
interface dynamicContentManagerProps {
|
||||
content: [] | any;
|
||||
}
|
||||
@ -91,7 +16,7 @@ interface dynamicContentManagerProps {
|
||||
const DynamicContentManager = ({ content }: dynamicContentManagerProps) => {
|
||||
return (
|
||||
<div className="dynamic-content overflow-x-hidden">
|
||||
{content.map(
|
||||
{content?.map(
|
||||
(
|
||||
component: { _type: string; _key: number; disabled: boolean; rest: any } | any,
|
||||
index: number
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Text from '@/components/ui/text';
|
||||
import { footerMenusQuery } from '@/lib/sanity/queries';
|
||||
import { clientFetch } from '@/lib/sanity/sanity.client';
|
||||
import { getCachedClient } from '@/lib/sanity/sanity.client';
|
||||
import LocaleSwitcher from 'components/ui/locale-switcher/locale-switcher';
|
||||
import Logo from 'components/ui/logo/logo';
|
||||
import Link from 'next/link';
|
||||
@ -15,7 +15,7 @@ export default async function Footer({ locale }: FooterProps) {
|
||||
locale: locale
|
||||
};
|
||||
|
||||
const footerMenus = await clientFetch(footerMenusQuery, params);
|
||||
const footerMenus = await getCachedClient()(footerMenusQuery, params);
|
||||
|
||||
return (
|
||||
<footer className="border-t border-ui-border bg-app">
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { categoriesQuery } from '@/lib/sanity/queries';
|
||||
import { clientFetch } from '@/lib/sanity/sanity.client';
|
||||
import { getCachedClient } from '@/lib/sanity/sanity.client';
|
||||
import Cart from 'components/cart';
|
||||
import OpenCart from 'components/cart/open-cart';
|
||||
import Logo from 'components/ui/logo/logo';
|
||||
@ -21,7 +21,7 @@ export default async function Header({ locale }: HeaderProps) {
|
||||
const params = {
|
||||
locale: locale
|
||||
};
|
||||
const mainMenu = await clientFetch(categoriesQuery, params);
|
||||
const mainMenu = await getCachedClient()(categoriesQuery, params);
|
||||
|
||||
return (
|
||||
<HeaderRoot>
|
||||
|
24
components/pages/home-page-preview.tsx
Normal file
24
components/pages/home-page-preview.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
'use client';
|
||||
|
||||
import { homePageQuery } from '@/lib/sanity/queries';
|
||||
import { useLiveQuery } from '@sanity/preview-kit';
|
||||
import PreviewBanner from '../ui/preview-banner';
|
||||
import HomePage from './home-page';
|
||||
|
||||
interface HomePagePreviewParams {
|
||||
initialData: [];
|
||||
params: {
|
||||
locale: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default function HomePagePreview({ initialData, params }: HomePagePreviewParams) {
|
||||
const [data] = useLiveQuery(initialData, homePageQuery, params);
|
||||
|
||||
return (
|
||||
<>
|
||||
<HomePage data={data} />;{/* @ts-ignore */}
|
||||
<PreviewBanner title={data?.title} />
|
||||
</>
|
||||
);
|
||||
}
|
13
components/pages/home-page.tsx
Normal file
13
components/pages/home-page.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import DynamicContentManager from '@/components/layout/dynamic-content-manager/dynamic-content-manager';
|
||||
|
||||
interface IndexPageParams {
|
||||
data: object | any;
|
||||
}
|
||||
|
||||
export default function HomePage({ data }: IndexPageParams) {
|
||||
return (
|
||||
<>
|
||||
<DynamicContentManager content={data?.content} />;
|
||||
</>
|
||||
);
|
||||
}
|
16
components/preview-provider.tsx
Normal file
16
components/preview-provider.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { getClient } from '@/lib/sanity/sanity.client';
|
||||
import { LiveQueryProvider } from '@sanity/preview-kit';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export default function PreviewProvider({
|
||||
children,
|
||||
token
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
token: string;
|
||||
}) {
|
||||
const client = useMemo(() => getClient({ token }), [token]);
|
||||
return <LiveQueryProvider client={client}>{children}</LiveQueryProvider>;
|
||||
}
|
@ -1,29 +1,30 @@
|
||||
'use client'
|
||||
'use client';
|
||||
|
||||
import { useTranslations } from 'next-intl'
|
||||
import Link from 'next/link'
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface PreviewBannerProps {
|
||||
title?: string
|
||||
title?: string;
|
||||
}
|
||||
|
||||
const PreviewBanner = ({ title }: PreviewBannerProps) => {
|
||||
const t = useTranslations('ui.previewBanner')
|
||||
const t = useTranslations('ui.previewBanner');
|
||||
return (
|
||||
<div className="flex justify-between items-center bg-app border-t border-high-contrast w-full fixed bottom-0 right-0 p-6 z-50">
|
||||
<div className="fixed bottom-0 right-0 z-50 flex w-full items-center justify-between border-t border-high-contrast bg-app p-6">
|
||||
{title && (
|
||||
<p className="text-lg">
|
||||
{t('titlePart')} <span className="italic font-bold">{title}</span>
|
||||
{t('titlePart')} <span className="font-bold italic">{title}</span>
|
||||
</p>
|
||||
)}
|
||||
<Link
|
||||
className="bg-blue transition-colors duration-100 text-center px-6 py-4 text-white font-bold hover:bg-opacity-80 focus:bg-opacity-80"
|
||||
href="/api/exit-draft"
|
||||
className="bg-blue px-6 py-4 text-center font-bold text-white transition-colors duration-100 hover:bg-opacity-80 focus:bg-opacity-80"
|
||||
href="/api/exit-preview"
|
||||
prefetch={false}
|
||||
>
|
||||
{t('exitPreviewLabel')}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default PreviewBanner
|
||||
export default PreviewBanner;
|
||||
|
@ -41,8 +41,10 @@ export const SANITY_API_VERSION = '2022-10-25'
|
||||
// Set this to enable helper links in document status banners and shortcut links on products and collections.
|
||||
export const STORM_STORE_ID = ''
|
||||
|
||||
export const SANITY_STUDIO_API_READ_TOKEN = process.env.SANITY_STUDIO_API_READ_TOKEN;
|
||||
|
||||
// Project preview URLs
|
||||
export const localStorefrontUrl = 'http://localhost:3000';
|
||||
export const localStorefrontPreviewUrl = 'http://localhost:3000/api/draft';
|
||||
export const localStorefrontPreviewUrl = 'http://localhost:3000/api/preview';
|
||||
export const publicStorefrontUrl = 'https://km-storefront.vercel.app';
|
||||
export const publicStorefrontPreviewUrl = 'https://km-storefront.vercel.app/api/draft';
|
||||
export const publicStorefrontPreviewUrl = 'https://km-storefront.vercel.app/api/preview';
|
@ -1,8 +1,8 @@
|
||||
import {ListItemBuilder} from 'sanity/desk'
|
||||
import defineStructure from '../utils/define-structure'
|
||||
import { EyeOpenIcon, MasterDetailIcon } from '@sanity/icons'
|
||||
import { SanityDocument } from 'sanity'
|
||||
import Iframe from 'sanity-plugin-iframe-pane'
|
||||
import {SanityDocument} from 'sanity'
|
||||
import {EyeOpenIcon, MasterDetailIcon} from '@sanity/icons'
|
||||
import { ListItemBuilder } from 'sanity/desk'
|
||||
import defineStructure from '../utils/define-structure'
|
||||
import getPreviewUrl from '../utils/get-preview-url'
|
||||
|
||||
export default defineStructure<ListItemBuilder>((S) =>
|
||||
|
@ -1,15 +1,31 @@
|
||||
import { createClient } from "next-sanity";
|
||||
import { cache } from 'react';
|
||||
import type { SanityClient } from "@sanity/client";
|
||||
import { createClient } from "@sanity/client";
|
||||
import { cache } from "react";
|
||||
|
||||
export const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!;
|
||||
export const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET!;
|
||||
const apiVersion = process.env.NEXT_PUBLIC_SANITY_API_VERSION!;
|
||||
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 client = createClient({
|
||||
projectId,
|
||||
dataset,
|
||||
apiVersion,
|
||||
useCdn: true,
|
||||
});
|
||||
export const getCachedClient = (preview?: {token?: string}) => {
|
||||
const client = getClient(preview);
|
||||
|
||||
export const clientFetch = cache(client.fetch.bind(client));
|
||||
return cache(client.fetch.bind(client));
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
import createImageUrlBuilder from '@sanity/image-url'
|
||||
import { client } from './sanity.client'
|
||||
import { getClient } from './sanity.client'
|
||||
|
||||
export const imageBuilder = createImageUrlBuilder(client)
|
||||
export const imageBuilder = createImageUrlBuilder(getClient())
|
||||
|
||||
export const urlForImage = (source: any) =>
|
||||
imageBuilder.image(source).auto('format').fit('crop')
|
||||
|
@ -1,20 +1,24 @@
|
||||
// @ts-nocheck
|
||||
import {isDev, SanityDocument} from 'sanity'
|
||||
import { isDev, SanityDocument } from 'sanity'
|
||||
import { localStorefrontPreviewUrl, publicStorefrontPreviewUrl } from '../constants'
|
||||
|
||||
const SANITY_STUDIO_API_READ_TOKEN = "skYG2HXNga8uxSL7rFIreJEnP0SdVjCZ2nzB8rUHD4wRWxXPGceXTuR5vCVBP99mWZ9ULhghmpUyX7EtzDmJusSk6Gwvdr3nLAsdWI9ZktIWvSWUNpHbu0Xfrrt0UUaktrLglk7ToABvjXlaPHLpOIR3dnjl4MGByutPmyra0b5t20kgDrmF"
|
||||
// Customise this function to show the correct URL based on the current document
|
||||
export default function getPreviewUrl(doc: SanityDocument) {
|
||||
export default async function getPreviewUrl(doc: SanityDocument) {
|
||||
|
||||
if (isDev) {
|
||||
// Home page have no slugs.
|
||||
if (!doc.slug) {
|
||||
return
|
||||
return `${localStorefrontPreviewUrl}?locale=${doc.language}&type=${doc._type}&secret=${SANITY_STUDIO_API_READ_TOKEN}`
|
||||
}
|
||||
|
||||
return `${localStorefrontPreviewUrl}?slug=${doc.slug.current}&locale=${doc.language}&secret=secret&type=${doc._type}`
|
||||
return `${localStorefrontPreviewUrl}?slug=${doc.slug.current}&locale=${doc.language}&type=${doc._type}&secret=${SANITY_STUDIO_API_READ_TOKEN}`
|
||||
} else {
|
||||
// Home page have no slugs.
|
||||
if (!doc.slug) {
|
||||
return
|
||||
return `${localStorefrontPreviewUrl}?locale=${doc.language}&type=${doc._type}&secret=${SANITY_STUDIO_API_READ_TOKEN}`
|
||||
}
|
||||
|
||||
return `${publicStorefrontPreviewUrl}?slug=${doc.slug.current}&locale=${doc.language}&secret=secret&type=${doc._type}`
|
||||
return `${publicStorefrontPreviewUrl}?slug=${doc.slug.current}&locale=${doc.language}&type=${doc._type}&secret=${SANITY_STUDIO_API_READ_TOKEN}`
|
||||
}
|
||||
}
|
@ -24,7 +24,12 @@ module.exports = withBundleAnalyzer(
|
||||
},
|
||||
images: {
|
||||
formats: ['image/avif', 'image/webp'],
|
||||
domains: ['cdn.sanity.io'],
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: 'https',
|
||||
hostname: 'cdn.sanity.io',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
|
@ -20,7 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@portabletext/react": "^3.0.0",
|
||||
"@portabletext/react": "^3.0.4",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||
@ -43,7 +43,7 @@
|
||||
"is-empty-iterable": "^3.0.0",
|
||||
"next": "13.4.13",
|
||||
"next-intl": "2.19.1",
|
||||
"next-sanity": "^4.3.2",
|
||||
"next-sanity": "^5.3.0",
|
||||
"react": "18.2.0",
|
||||
"react-cookie": "^4.1.1",
|
||||
"react-dom": "18.2.0",
|
||||
|
126
pnpm-lock.yaml
generated
126
pnpm-lock.yaml
generated
@ -9,7 +9,7 @@ dependencies:
|
||||
specifier: ^2.0.18
|
||||
version: 2.0.18(react@18.2.0)
|
||||
'@portabletext/react':
|
||||
specifier: ^3.0.0
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4(react@18.2.0)
|
||||
'@radix-ui/react-accordion':
|
||||
specifier: ^1.1.2
|
||||
@ -78,8 +78,8 @@ dependencies:
|
||||
specifier: 2.19.1
|
||||
version: 2.19.1(next@13.4.13)(react@18.2.0)
|
||||
next-sanity:
|
||||
specifier: ^4.3.2
|
||||
version: 4.3.3(@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)
|
||||
specifier: ^5.3.0
|
||||
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)
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@ -2218,23 +2218,6 @@ packages:
|
||||
resolution: {integrity: sha512-wtMYcV5GIDIhVyF/jjmdwq1GdlK07dRL40XMns73VbrFI7FteRltxv48bhYVZPcLkRXb0SHjpDS/icj9/yzbVA==}
|
||||
dev: false
|
||||
|
||||
/@sanity/groq-store@2.3.4:
|
||||
resolution: {integrity: sha512-7W3ROK858YuAjyoPp9+OfHj00BkJX172b6LyV9peL8DcbMIG0G621Tv+oULLaizkA4y2D+b1sx+AYHWtdtIrew==}
|
||||
engines: {node: '>=14.18'}
|
||||
dependencies:
|
||||
'@sanity/eventsource': 5.0.0
|
||||
'@sanity/types': 3.15.0
|
||||
fast-deep-equal: 3.1.3
|
||||
groq: 3.15.0
|
||||
groq-js: 1.1.10
|
||||
mendoza: 2.1.2
|
||||
simple-get: 4.0.1
|
||||
split2: 4.2.0
|
||||
throttle-debounce: 5.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/groq-store@4.0.3:
|
||||
resolution: {integrity: sha512-6mXBUvOrsSG9G7OP52VQMd114+s1AjkrJZCUIaFlZGJTamFvd8viCgZuykEt5wURIm3nVnx3MmWDZPFCvLvNuQ==}
|
||||
engines: {node: '>=14.18'}
|
||||
@ -2252,6 +2235,23 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/groq-store@4.0.4:
|
||||
resolution: {integrity: sha512-Bk1ZsS6PGeCtmP8a4FJfvHws1WlnQUPdcr9MbO38Fbbtp55ZdLjTbxozxo//mK7jsbmNxf2HjpQ1mm5jDI49RQ==}
|
||||
engines: {node: '>=14.18'}
|
||||
dependencies:
|
||||
'@sanity/eventsource': 5.0.0
|
||||
'@sanity/types': 3.15.0
|
||||
fast-deep-equal: 3.1.3
|
||||
groq: 3.15.0
|
||||
groq-js: 1.1.12
|
||||
mendoza: 3.0.3
|
||||
simple-get: 4.0.1
|
||||
split2: 4.2.0
|
||||
throttle-debounce: 5.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/icons@1.3.10(react@18.2.0):
|
||||
resolution: {integrity: sha512-5wVG/vIiGuGrSmq+Bl3PY7XDgQrGv0fyHdJI64FSulnr2wH3NMqZ6C59UFxnrZ93sr7kOt0zQFoNv2lkPBi0Cg==}
|
||||
peerDependencies:
|
||||
@ -2381,24 +2381,6 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/preview-kit@1.5.5(react@18.2.0):
|
||||
resolution: {integrity: sha512-RJ+bcLB0cH2vyzqyhb4WMua3xygx4em2fuooKOETo1Z/HyyXqFfWZgCRvFItLS5erKNr0pz7Mbhq7sWhGmuOtg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
react: ^18.0.0
|
||||
dependencies:
|
||||
'@sanity/client': 6.4.4
|
||||
'@sanity/eventsource': 5.0.0
|
||||
'@sanity/groq-store': 2.3.4
|
||||
'@vercel/stega': 0.0.5
|
||||
lodash.isplainobject: 4.0.6
|
||||
react: 18.2.0
|
||||
suspend-react: 0.0.10(react@18.2.0)
|
||||
tiny-invariant: 1.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/preview-kit@2.4.9(@sanity/client@6.4.4)(react@18.2.0):
|
||||
resolution: {integrity: sha512-0j7An0beiMOTMLA+RdzQmAo6Lk6YuKuuARabKTk6rpl4uf117jtveh50DiaZNHieToF9AGXxc9qgYXR0lc4k+w==}
|
||||
engines: {node: '>=14'}
|
||||
@ -2424,6 +2406,31 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/preview-kit@3.0.0(@sanity/client@6.4.4)(react@18.2.0):
|
||||
resolution: {integrity: sha512-LF83FQJ0kZgB8Dz8nolseiXh+AsX0UaNd3GhNLMrsmSjy6GCagNyQzCpadysQyuBZHftXgMN/fQ0/gfoMjNSDA==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@sanity/client': ^6.4.6
|
||||
react: ^18.0.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@sanity/client': 6.4.4
|
||||
'@sanity/eventsource': 5.0.0
|
||||
'@sanity/groq-store': 4.0.4
|
||||
'@vercel/stega': 0.1.0
|
||||
lodash.get: 4.4.2
|
||||
lodash.isplainobject: 4.0.6
|
||||
lru-cache: 10.0.1
|
||||
mendoza: 3.0.3
|
||||
react: 18.2.0
|
||||
react-fast-compare: 3.2.2
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sanity/schema@3.15.0:
|
||||
resolution: {integrity: sha512-x6KSZkfBnVPFkHyuCKcaXZbu8C76qUkRtczZ5DNvFQbIxHYGMzUuQTDm7JBATt1c3KKM4nSR5xXwsh6IzuM5+w==}
|
||||
dependencies:
|
||||
@ -2927,10 +2934,6 @@ packages:
|
||||
ajv: 6.12.6
|
||||
dev: false
|
||||
|
||||
/@vercel/stega@0.0.5:
|
||||
resolution: {integrity: sha512-vvuUYW0rBp4Ea9xv0LilqFyDHAW9tvy4GL70G1ayGisQwpOYIPChmiw/56jqZvpxjE9gjQIApLfglOcdZe3PcA==}
|
||||
dev: false
|
||||
|
||||
/@vercel/stega@0.1.0:
|
||||
resolution: {integrity: sha512-5b0PkOJsFBX5alChuIO3qpkt5vIZBevzLPhUQ1UP8UzVjL3F1VllnZxp/thfD8R5ol7D7WHkgZHIjdUBX4tDpQ==}
|
||||
dev: false
|
||||
@ -5065,13 +5068,13 @@ packages:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
dev: true
|
||||
|
||||
/groq-js@1.1.10:
|
||||
resolution: {integrity: sha512-cYZMSCuBZ5KPB7hDRzkIwTB6qTDtcfqXxcejJPWumSw5gCOInTSvVtfccp0GM7TE1HkF7bF1PR2iSnliFDSSJg==}
|
||||
/groq-js@1.1.11:
|
||||
resolution: {integrity: sha512-LLYg7+nuOOcbQD7FKJjZj442W4ws+j/yggJV474VS6kmeIpBxfNGNMnBsfGSaJ/iDIhknjL4OcDgJ60FL+UJXA==}
|
||||
engines: {node: '>= 14'}
|
||||
dev: false
|
||||
|
||||
/groq-js@1.1.11:
|
||||
resolution: {integrity: sha512-LLYg7+nuOOcbQD7FKJjZj442W4ws+j/yggJV474VS6kmeIpBxfNGNMnBsfGSaJ/iDIhknjL4OcDgJ60FL+UJXA==}
|
||||
/groq-js@1.1.12:
|
||||
resolution: {integrity: sha512-02KhsoLuTwr/MOf6bBzt+rQOj+QuLoZ5IDDkzXM2NWY73CF1d29KTRBffzCAjsjBvY7kn+oQcwPdQVb3vBkl9w==}
|
||||
engines: {node: '>= 14'}
|
||||
dev: false
|
||||
|
||||
@ -5889,6 +5892,11 @@ packages:
|
||||
engines: {node: 14 || >=16.14}
|
||||
dev: false
|
||||
|
||||
/lru-cache@10.0.1:
|
||||
resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==}
|
||||
engines: {node: 14 || >=16.14}
|
||||
dev: false
|
||||
|
||||
/lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
dependencies:
|
||||
@ -5920,11 +5928,6 @@ packages:
|
||||
resolution: {integrity: sha512-mXfNXte0RSWl0rEIsQhXutfM2R2Oa7UyKDD7XoZMEbKeucTRms04y5y41U8gLqPzRx7ViN/QyYnTR2TX/5tawA==}
|
||||
dev: false
|
||||
|
||||
/mendoza@2.1.2:
|
||||
resolution: {integrity: sha512-Z2orUYO/RR7hJ2WdMtE1+u7X3/FiZrUpZqdctjxjxAfRODHfSvHKH+5tdEq/dXCf3W3CXSqWM46Ye7ww+KMrtQ==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/mendoza@3.0.3:
|
||||
resolution: {integrity: sha512-xh0Angj7/kuLzJHglH7dVetoSyUt1/2wjmuugB0iBftteS6+xKvwC+bhs+IvF9tITdEdZpIl0XT5QLaL18A5dA==}
|
||||
engines: {node: '>=14.18'}
|
||||
@ -6091,10 +6094,11 @@ packages:
|
||||
use-intl: 2.19.1(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/next-sanity@4.3.3(@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-537xLC4hpTgV3SGj6w4aXvBvm/nHdyZGtZ5IcZpH33p70J7UjptF4+D4FvWKZGPjF3v3SFk75AHjxWVPORL9RA==}
|
||||
engines: {node: '>=16'}
|
||||
/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):
|
||||
resolution: {integrity: sha512-cBeO3QgIjR9UPjDedNfLT4m6vmeFlDn9HAVT/6q8CbMMf+bcpxQ94jpLGGkaPRzoeCy/XWKK4IXNQYDSs4ApIA==}
|
||||
engines: {node: '>=16.14'}
|
||||
peerDependencies:
|
||||
'@sanity/client': ^6.4.6
|
||||
'@sanity/icons': ^2.0.0
|
||||
'@sanity/types': ^3.0.0
|
||||
'@sanity/ui': ^1.0.0
|
||||
@ -6106,7 +6110,7 @@ packages:
|
||||
dependencies:
|
||||
'@sanity/client': 6.4.4
|
||||
'@sanity/icons': 2.4.1(react@18.2.0)
|
||||
'@sanity/preview-kit': 1.5.5(react@18.2.0)
|
||||
'@sanity/preview-kit': 3.0.0(@sanity/client@6.4.4)(react@18.2.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/webhook': 2.0.0
|
||||
@ -8150,14 +8154,6 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
/suspend-react@0.0.10(react@18.2.0):
|
||||
resolution: {integrity: sha512-7yyJ1aBr9Ap4XZQOBaYlOelNcRc42zv50C0pVNOHfhW/DwTbHGFVZKKJsVndyQvQTv/fAkIO9TAMvGiSCjT0Zw==}
|
||||
peerDependencies:
|
||||
react: '>=17.0'
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/suspend-react@0.0.8(react@18.2.0):
|
||||
resolution: {integrity: sha512-ZC3r8Hu1y0dIThzsGw0RLZplnX9yXwfItcvaIzJc2VQVi8TGyGDlu92syMB5ulybfvGLHAI5Ghzlk23UBPF8xg==}
|
||||
peerDependencies:
|
||||
@ -8303,10 +8299,6 @@ packages:
|
||||
resolution: {integrity: sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA==}
|
||||
dev: false
|
||||
|
||||
/tiny-invariant@1.3.1:
|
||||
resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==}
|
||||
dev: false
|
||||
|
||||
/tiny-warning@1.0.3:
|
||||
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
||||
dev: false
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {defineConfig, isDev} from 'sanity'
|
||||
import {deskTool} from 'sanity/desk'
|
||||
import {visionTool} from '@sanity/vision'
|
||||
import {media} from 'sanity-plugin-media'
|
||||
import {schemaTypes} from '@/lib/sanity/schemas'
|
||||
import {structure} from '@/lib/sanity/desk'
|
||||
import Kodamera from '@/lib/sanity/components/icons/kodamera'
|
||||
import {documentInternationalization} from '@sanity/document-internationalization'
|
||||
import { structure } from '@/lib/sanity/desk'
|
||||
import { schemaTypes } from '@/lib/sanity/schemas'
|
||||
import { documentInternationalization } from '@sanity/document-internationalization'
|
||||
import { visionTool } from '@sanity/vision'
|
||||
import { defineConfig, isDev } from 'sanity'
|
||||
import { media } from 'sanity-plugin-media'
|
||||
import { deskTool } from 'sanity/desk'
|
||||
|
||||
const devOnlyPlugins = [visionTool()]
|
||||
|
||||
@ -15,6 +15,8 @@ const singletonActions = new Set(["publish", "discardChanges", "restore"])
|
||||
// Define the singleton document types
|
||||
const singletonTypes = new Set(["settings", "home", "utilityMenu", "media.tag"])
|
||||
|
||||
// console.log(process.env.SANITY_API_READ_TOKEN)
|
||||
|
||||
export default defineConfig({
|
||||
name: 'default',
|
||||
title: 'KM Storefront CMS',
|
||||
|
Loading…
x
Reference in New Issue
Block a user