mirror of
https://github.com/vercel/commerce.git
synced 2025-05-16 14:36:59 +00:00
Add analytics events
This commit is contained in:
parent
7f2c67d357
commit
8024f51fb4
@ -1,8 +1,8 @@
|
|||||||
|
import { Analytics } from '@vercel/analytics/react';
|
||||||
import Navbar from 'components/layout/navbar';
|
import Navbar from 'components/layout/navbar';
|
||||||
import { Inter } from 'next/font/google';
|
import { Inter } from 'next/font/google';
|
||||||
import { ReactNode, Suspense } from 'react';
|
import { ReactNode, Suspense } from 'react';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
|
|
||||||
const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env;
|
const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env;
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
@ -39,6 +39,7 @@ export default async function RootLayout({ children }: { children: ReactNode })
|
|||||||
<Suspense>
|
<Suspense>
|
||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
<Analytics />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
@ -68,7 +68,7 @@ export default async function ProductPage({ params }: { params: { handle: string
|
|||||||
currencyCode={product.priceRange.maxVariantPrice.currencyCode}
|
currencyCode={product.priceRange.maxVariantPrice.currencyCode}
|
||||||
images={product.images.map((image: Image) => ({
|
images={product.images.map((image: Image) => ({
|
||||||
src: image.url,
|
src: image.url,
|
||||||
altText: image.altText
|
altText: image?.altText
|
||||||
}))}
|
}))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@ import { useCookies } from 'react-cookie';
|
|||||||
import CartIcon from 'components/icons/cart';
|
import CartIcon from 'components/icons/cart';
|
||||||
import CartModal from './modal';
|
import CartModal from './modal';
|
||||||
|
|
||||||
|
import { track } from '@vercel/analytics/react';
|
||||||
import type { Cart } from 'lib/shopify/types';
|
import type { Cart } from 'lib/shopify/types';
|
||||||
|
|
||||||
export default function CartButton({
|
export default function CartButton({
|
||||||
@ -53,6 +54,7 @@ export default function CartButton({
|
|||||||
aria-label="Open cart"
|
aria-label="Open cart"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCartIsOpen(true);
|
setCartIsOpen(true);
|
||||||
|
track('Open Cart', { quantity: cart.totalQuantity, cartId: cart.id });
|
||||||
}}
|
}}
|
||||||
className="relative right-0 top-0"
|
className="relative right-0 top-0"
|
||||||
data-testid="open-cart"
|
data-testid="open-cart"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { track } from '@vercel/analytics';
|
||||||
import CloseIcon from 'components/icons/close';
|
import CloseIcon from 'components/icons/close';
|
||||||
import LoadingDots from 'components/loading-dots';
|
import LoadingDots from 'components/loading-dots';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
@ -21,6 +22,11 @@ export default function DeleteItemButton({ item }: { item: CartItem }) {
|
|||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
track('Remove From Cart', {
|
||||||
|
merchandiseId: item.id,
|
||||||
|
quantity: item.quantity
|
||||||
|
});
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
alert(data.error);
|
alert(data.error);
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { startTransition, useState } from 'react';
|
import { startTransition, useState } from 'react';
|
||||||
|
|
||||||
|
import { track } from '@vercel/analytics';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import MinusIcon from 'components/icons/minus';
|
import MinusIcon from 'components/icons/minus';
|
||||||
import PlusIcon from 'components/icons/plus';
|
import PlusIcon from 'components/icons/plus';
|
||||||
@ -20,17 +21,26 @@ export default function EditItemQuantityButton({
|
|||||||
async function handleEdit() {
|
async function handleEdit() {
|
||||||
setEditing(true);
|
setEditing(true);
|
||||||
|
|
||||||
|
const quantity = type === 'plus' ? item.quantity + 1 : item.quantity - 1;
|
||||||
|
|
||||||
const response = await fetch(`/api/cart`, {
|
const response = await fetch(`/api/cart`, {
|
||||||
method: type === 'minus' && item.quantity - 1 === 0 ? 'DELETE' : 'PUT',
|
method: type === 'minus' && item.quantity - 1 === 0 ? 'DELETE' : 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
lineId: item.id,
|
lineId: item.id,
|
||||||
variantId: item.merchandise.id,
|
variantId: item.merchandise.id,
|
||||||
quantity: type === 'plus' ? item.quantity + 1 : item.quantity - 1
|
quantity
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
track('Change Item Quantity', {
|
||||||
|
merchandiseId: item.id,
|
||||||
|
quantity,
|
||||||
|
type: type === 'plus' ? 'increase' : 'decrease',
|
||||||
|
name: item.merchandise.title
|
||||||
|
});
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
alert(data.error);
|
alert(data.error);
|
||||||
return;
|
return;
|
||||||
|
@ -3,6 +3,7 @@ import { AnimatePresence, motion } from 'framer-motion';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
import { track } from '@vercel/analytics';
|
||||||
import CloseIcon from 'components/icons/close';
|
import CloseIcon from 'components/icons/close';
|
||||||
import ShoppingBagIcon from 'components/icons/shopping-bag';
|
import ShoppingBagIcon from 'components/icons/shopping-bag';
|
||||||
import Price from 'components/price';
|
import Price from 'components/price';
|
||||||
@ -172,6 +173,13 @@ export default function CartModal({
|
|||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
href={cart.checkoutUrl}
|
href={cart.checkoutUrl}
|
||||||
|
onClick={() => {
|
||||||
|
track('Checkout', {
|
||||||
|
cartId: cart.id,
|
||||||
|
cartTotal: cart.cost.totalAmount.amount,
|
||||||
|
cartCurrency: cart.cost.totalAmount.currencyCode
|
||||||
|
});
|
||||||
|
}}
|
||||||
className="flex w-full items-center justify-center bg-black p-3 text-sm font-medium uppercase text-white opacity-90 hover:opacity-100 dark:bg-white dark:text-black"
|
className="flex w-full items-center justify-center bg-black p-3 text-sm font-medium uppercase text-white opacity-90 hover:opacity-100 dark:bg-white dark:text-black"
|
||||||
>
|
>
|
||||||
<span>Proceed to Checkout</span>
|
<span>Proceed to Checkout</span>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
|
|
||||||
|
import { track } from '@vercel/analytics';
|
||||||
import SearchIcon from 'components/icons/search';
|
import SearchIcon from 'components/icons/search';
|
||||||
|
|
||||||
export default function Search() {
|
export default function Search() {
|
||||||
@ -16,6 +17,10 @@ export default function Search() {
|
|||||||
|
|
||||||
if (search.value) {
|
if (search.value) {
|
||||||
router.push(`/search?q=${search.value}`);
|
router.push(`/search?q=${search.value}`);
|
||||||
|
|
||||||
|
track('Search', {
|
||||||
|
query: search.value
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
router.push(`/search`);
|
router.push(`/search`);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { track } from '@vercel/analytics';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
import { useEffect, useState, useTransition } from 'react';
|
import { useEffect, useState, useTransition } from 'react';
|
||||||
@ -14,7 +15,7 @@ export function AddToCart({
|
|||||||
variants: ProductVariant[];
|
variants: ProductVariant[];
|
||||||
availableForSale: boolean;
|
availableForSale: boolean;
|
||||||
}) {
|
}) {
|
||||||
const [selectedVariantId, setSelectedVariantId] = useState(variants[0]?.id);
|
const [selectedVariant, setSelectedVariant] = useState(variants[0]);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
@ -28,9 +29,9 @@ export function AddToCart({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (variant) {
|
if (variant) {
|
||||||
setSelectedVariantId(variant.id);
|
setSelectedVariant(variant);
|
||||||
}
|
}
|
||||||
}, [searchParams, variants, setSelectedVariantId]);
|
}, [searchParams, variants, setSelectedVariant]);
|
||||||
|
|
||||||
const isMutating = adding || isPending;
|
const isMutating = adding || isPending;
|
||||||
|
|
||||||
@ -42,10 +43,18 @@ export function AddToCart({
|
|||||||
const response = await fetch(`/api/cart`, {
|
const response = await fetch(`/api/cart`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
merchandiseId: selectedVariantId
|
merchandiseId: selectedVariant?.id
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
track('Add To Cart', {
|
||||||
|
merchandiseId: selectedVariant?.id || null,
|
||||||
|
name: selectedVariant?.title || null,
|
||||||
|
price: selectedVariant?.price.amount || null,
|
||||||
|
currency: selectedVariant?.price.currencyCode || null,
|
||||||
|
quantity: 1
|
||||||
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^1.7.10",
|
"@headlessui/react": "^1.7.10",
|
||||||
|
"@vercel/analytics": "^1.0.0",
|
||||||
"@vercel/og": "^0.1.0",
|
"@vercel/og": "^0.1.0",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"framer-motion": "^8.4.0",
|
"framer-motion": "^8.4.0",
|
||||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -7,6 +7,7 @@ specifiers:
|
|||||||
'@types/node': 18.13.0
|
'@types/node': 18.13.0
|
||||||
'@types/react': 18.0.27
|
'@types/react': 18.0.27
|
||||||
'@types/react-dom': 18.0.10
|
'@types/react-dom': 18.0.10
|
||||||
|
'@vercel/analytics': ^1.0.0
|
||||||
'@vercel/git-hooks': ^1.0.0
|
'@vercel/git-hooks': ^1.0.0
|
||||||
'@vercel/og': ^0.1.0
|
'@vercel/og': ^0.1.0
|
||||||
autoprefixer: ^10.4.13
|
autoprefixer: ^10.4.13
|
||||||
@ -30,6 +31,7 @@ specifiers:
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@headlessui/react': 1.7.14_biqbaboplfbrettd7655fr4n2y
|
'@headlessui/react': 1.7.14_biqbaboplfbrettd7655fr4n2y
|
||||||
|
'@vercel/analytics': 1.0.0_react@18.2.0
|
||||||
'@vercel/og': 0.1.0
|
'@vercel/og': 0.1.0
|
||||||
clsx: 1.2.1
|
clsx: 1.2.1
|
||||||
framer-motion: 8.5.5_biqbaboplfbrettd7655fr4n2y
|
framer-motion: 8.5.5_biqbaboplfbrettd7655fr4n2y
|
||||||
@ -526,6 +528,14 @@ packages:
|
|||||||
eslint-visitor-keys: 3.4.0
|
eslint-visitor-keys: 3.4.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@vercel/analytics/1.0.0_react@18.2.0:
|
||||||
|
resolution: {integrity: sha512-RQmj7pv82JwGDHrnKeRc6TtSw2U7rWNubc2IH0ernTzWTj02yr9zvIYiYJeztsBzrJtWv7m8Nz6vxxb+cdEtJw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8||^17||^18
|
||||||
|
dependencies:
|
||||||
|
react: 18.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@vercel/git-hooks/1.0.0:
|
/@vercel/git-hooks/1.0.0:
|
||||||
resolution: {integrity: sha512-OxDFAAdyiJ/H0b8zR9rFCu3BIb78LekBXOphOYG3snV4ULhKFX387pBPpqZ9HLiRTejBWBxYEahkw79tuIgdAA==}
|
resolution: {integrity: sha512-OxDFAAdyiJ/H0b8zR9rFCu3BIb78LekBXOphOYG3snV4ULhKFX387pBPpqZ9HLiRTejBWBxYEahkw79tuIgdAA==}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user