diff --git a/.gitignore b/.gitignore index 0298027e4..e82a0f9db 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts +.env*.local diff --git a/app/[page]/opengraph-image.tsx b/app/[page]/opengraph-image.tsx index 2fd59281e..031e73fc8 100644 --- a/app/[page]/opengraph-image.tsx +++ b/app/[page]/opengraph-image.tsx @@ -1,8 +1,6 @@ import OpengraphImage from 'components/opengraph-image'; import { getPage } from 'lib/shopify'; -export const runtime = 'edge'; - export default async function Image({ params }: { params: { page: string } }) { const page = await getPage(params.page); const title = page.seo?.title || page.title; diff --git a/app/globals.css b/app/globals.css index 0a6d36768..78b24be67 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,6 +1,17 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import 'tailwindcss'; + +@plugin "@tailwindcss/container-queries"; +@plugin "@tailwindcss/typography"; + +@layer base { + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentColor); + } +} @media (prefers-color-scheme: dark) { html { @@ -17,5 +28,5 @@ a, input, button { - @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-50 dark:focus-visible:ring-neutral-600 dark:focus-visible:ring-offset-neutral-900; + @apply focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-50 dark:focus-visible:ring-neutral-600 dark:focus-visible:ring-offset-neutral-900; } diff --git a/app/layout.tsx b/app/layout.tsx index 348adcecb..5e3355ce9 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,18 +3,12 @@ import { Navbar } from 'components/layout/navbar'; import { WelcomeToast } from 'components/welcome-toast'; import { GeistSans } from 'geist/font/sans'; import { getCart } from 'lib/shopify'; -import { ensureStartsWith } from 'lib/utils'; -import { cookies } from 'next/headers'; import { ReactNode } from 'react'; import { Toaster } from 'sonner'; import './globals.css'; +import { baseUrl } from 'lib/utils'; -const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env; -const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL - ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` - : 'http://localhost:3000'; -const twitterCreator = TWITTER_CREATOR ? ensureStartsWith(TWITTER_CREATOR, '@') : undefined; -const twitterSite = TWITTER_SITE ? ensureStartsWith(TWITTER_SITE, 'https://') : undefined; +const { SITE_NAME } = process.env; export const metadata = { metadataBase: new URL(baseUrl), @@ -25,21 +19,16 @@ export const metadata = { robots: { follow: true, index: true - }, - ...(twitterCreator && - twitterSite && { - twitter: { - card: 'summary_large_image', - creator: twitterCreator, - site: twitterSite - } - }) + } }; -export default async function RootLayout({ children }: { children: ReactNode }) { - const cartId = (await cookies()).get('cartId')?.value; +export default async function RootLayout({ + children +}: { + children: ReactNode; +}) { // Don't await the fetch, pass the Promise to the context provider - const cart = getCart(cartId); + const cart = getCart(); return ( diff --git a/app/opengraph-image.tsx b/app/opengraph-image.tsx index 23762cbdd..7a6f49f46 100644 --- a/app/opengraph-image.tsx +++ b/app/opengraph-image.tsx @@ -1,7 +1,5 @@ import OpengraphImage from 'components/opengraph-image'; -export const runtime = 'edge'; - export default async function Image() { return await OpengraphImage(); } diff --git a/app/page.tsx b/app/page.tsx index 7d407ede8..7c4a7d74f 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -3,7 +3,8 @@ import { ThreeItemGrid } from 'components/grid/three-items'; import Footer from 'components/layout/footer'; export const metadata = { - description: 'High-performance ecommerce store built with Next.js, Vercel, and Shopify.', + description: + 'High-performance ecommerce store built with Next.js, Vercel, and Shopify.', openGraph: { type: 'website' } diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 295b8b005..33de3c0ba 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -80,7 +80,7 @@ export default async function ProductPage(props: { params: Promise<{ handle: str __html: JSON.stringify(productJsonLd) }} /> -
+
-
+
- {children} + + {children} +
diff --git a/app/sitemap.ts b/app/sitemap.ts index 8f31ee94f..df3eb4736 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,5 +1,5 @@ import { getCollections, getPages, getProducts } from 'lib/shopify'; -import { validateEnvironmentVariables } from 'lib/utils'; +import { baseUrl, validateEnvironmentVariables } from 'lib/utils'; import { MetadataRoute } from 'next'; type Route = { @@ -7,10 +7,6 @@ type Route = { lastModified: string; }; -const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL - ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` - : 'http://localhost:3000'; - export const dynamic = 'force-dynamic'; export default async function sitemap(): Promise { @@ -45,7 +41,9 @@ export default async function sitemap(): Promise { let fetchedRoutes: Route[] = []; try { - fetchedRoutes = (await Promise.all([collectionsPromise, productsPromise, pagesPromise])).flat(); + fetchedRoutes = ( + await Promise.all([collectionsPromise, productsPromise, pagesPromise]) + ).flat(); } catch (error) { throw JSON.stringify(error, null, 2); } diff --git a/components/cart/actions.ts b/components/cart/actions.ts index 8f2255719..361daf64d 100644 --- a/components/cart/actions.ts +++ b/components/cart/actions.ts @@ -1,20 +1,27 @@ 'use server'; import { TAGS } from 'lib/constants'; -import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/shopify'; +import { + addToCart, + createCart, + getCart, + removeFromCart, + updateCart +} from 'lib/shopify'; import { revalidateTag } from 'next/cache'; import { cookies } from 'next/headers'; import { redirect } from 'next/navigation'; -export async function addItem(prevState: any, selectedVariantId: string | undefined) { - let cartId = (await cookies()).get('cartId')?.value; - - if (!cartId || !selectedVariantId) { +export async function addItem( + prevState: any, + selectedVariantId: string | undefined +) { + if (!selectedVariantId) { return 'Error adding item to cart'; } try { - await addToCart(cartId, [{ merchandiseId: selectedVariantId, quantity: 1 }]); + await addToCart([{ merchandiseId: selectedVariantId, quantity: 1 }]); revalidateTag(TAGS.cart); } catch (e) { return 'Error adding item to cart'; @@ -22,23 +29,19 @@ export async function addItem(prevState: any, selectedVariantId: string | undefi } export async function removeItem(prevState: any, merchandiseId: string) { - let cartId = (await cookies()).get('cartId')?.value; - - if (!cartId) { - return 'Missing cart ID'; - } - try { - const cart = await getCart(cartId); + const cart = await getCart(); if (!cart) { return 'Error fetching cart'; } - const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId); + const lineItem = cart.lines.find( + (line) => line.merchandise.id === merchandiseId + ); if (lineItem && lineItem.id) { - await removeFromCart(cartId, [lineItem.id]); + await removeFromCart([lineItem.id]); revalidateTag(TAGS.cart); } else { return 'Item not found in cart'; @@ -55,28 +58,24 @@ export async function updateItemQuantity( quantity: number; } ) { - let cartId = (await cookies()).get('cartId')?.value; - - if (!cartId) { - return 'Missing cart ID'; - } - const { merchandiseId, quantity } = payload; try { - const cart = await getCart(cartId); + const cart = await getCart(); if (!cart) { return 'Error fetching cart'; } - const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId); + const lineItem = cart.lines.find( + (line) => line.merchandise.id === merchandiseId + ); if (lineItem && lineItem.id) { if (quantity === 0) { - await removeFromCart(cartId, [lineItem.id]); + await removeFromCart([lineItem.id]); } else { - await updateCart(cartId, [ + await updateCart([ { id: lineItem.id, merchandiseId, @@ -86,7 +85,7 @@ export async function updateItemQuantity( } } else if (quantity > 0) { // If the item doesn't exist in the cart and quantity > 0, add it - await addToCart(cartId, [{ merchandiseId, quantity }]); + await addToCart([{ merchandiseId, quantity }]); } revalidateTag(TAGS.cart); @@ -97,9 +96,7 @@ export async function updateItemQuantity( } export async function redirectToCheckout() { - let cartId = (await cookies()).get('cartId')?.value; - let cart = await getCart(cartId); - + let cart = await getCart(); redirect(cart!.checkoutUrl); } diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index dc7ca596b..85e13073d 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -27,7 +27,6 @@ function SubmitButton({ ); } - console.log(selectedVariantId); if (!selectedVariantId) { return (