Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a9f676b
Add storefront product grid with image support
wcole1-godaddy Nov 7, 2025
d9a5aef
load styles from provider for exported components
pbennett1-godaddy Nov 7, 2025
f28fb20
product details page with option tracking
pbennett1-godaddy Nov 7, 2025
9ab5c9c
add storeId and clientId to gd provider context
pbennett1-godaddy Nov 7, 2025
e8cf37b
add cart and router link support
pbennett1-godaddy Nov 7, 2025
009704b
comment out image dupe testing
pbennett1-godaddy Nov 7, 2025
a791386
Merge branch 'main' of https://github.com/godaddy/javascript into sto…
pbennett1-godaddy Nov 10, 2025
c6cde4b
update providers and skus query
pbennett1-godaddy Nov 10, 2025
0c578af
add storefront schema
pbennett1-godaddy Nov 11, 2025
19220b7
refactor gql for namespacing
pbennett1-godaddy Nov 11, 2025
e8e5057
fix input usage for storefront skus
pbennett1-godaddy Nov 11, 2025
ae1492f
load in attributes
pbennett1-godaddy Nov 11, 2025
a642c4a
add orders schemas and graphql
pbennett1-godaddy Nov 11, 2025
295579e
Potential fix for code scanning alert no. 1: Incomplete URL scheme check
pbennett1-godaddy Nov 11, 2025
635e559
Potential fix for code scanning alert no. 2: Incomplete URL scheme check
pbennett1-godaddy Nov 11, 2025
8da4f66
add lucide to example nextjs app
pbennett1-godaddy Nov 11, 2025
d1d533d
replace sku with productId
pbennett1-godaddy Nov 11, 2025
e53ea92
add return URL logic back
pbennett1-godaddy Nov 11, 2025
38627f9
use skuGroup for product-details
pbennett1-godaddy Nov 11, 2025
3a88835
remove nuqs dep
pbennett1-godaddy Nov 11, 2025
5117ea0
Small style updates to product grid and details
wcole1-godaddy Nov 13, 2025
69b0029
add changeset
pbennett1-godaddy Nov 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cute-bees-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@godaddy/react": patch
---

Add product grid and product details components using public storefront apis
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ dist
/blob-report/
/playwright/.cache/

schema.graphql
*.graphql

# macOS
.DS_Store
Expand Down
42 changes: 19 additions & 23 deletions examples/nextjs/app/checkout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use client';

import type { CheckoutFormSchema, CheckoutSession } from '@godaddy/react';
import { Checkout, GoDaddyProvider } from '@godaddy/react';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { Checkout } from '@godaddy/react';
import { z } from 'zod';

/* Override the checkout form schema to make shippingPhone required */
Expand All @@ -12,26 +11,23 @@ const customSchema: CheckoutFormSchema = {

export function CheckoutPage({ session }: { session: CheckoutSession }) {
return (
<GoDaddyProvider apiHost={process.env.NEXT_PUBLIC_GODADDY_API_HOST}>
<Checkout
session={session}
checkoutFormSchema={customSchema}
squareConfig={{
appId: process.env.NEXT_PUBLIC_SQUARE_APP_ID || '',
locationId: process.env.NEXT_PUBLIC_SQUARE_LOCATION_ID || '',
}}
stripeConfig={{
publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || '',
}}
godaddyPaymentsConfig={{
businessId: process.env.NEXT_PUBLIC_GODADDY_BUSINESS_ID || '',
appId: process.env.NEXT_PUBLIC_GODADDY_APP_ID || '',
}}
paypalConfig={{
clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || '',
}}
/>
<ReactQueryDevtools initialIsOpen={false} />
</GoDaddyProvider>
<Checkout
session={session}
checkoutFormSchema={customSchema}
squareConfig={{
appId: process.env.NEXT_PUBLIC_SQUARE_APP_ID || '',
locationId: process.env.NEXT_PUBLIC_SQUARE_LOCATION_ID || '',
}}
stripeConfig={{
publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || '',
}}
godaddyPaymentsConfig={{
businessId: process.env.NEXT_PUBLIC_GODADDY_BUSINESS_ID || '',
appId: process.env.NEXT_PUBLIC_GODADDY_APP_ID || '',
}}
paypalConfig={{
clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || '',
}}
/>
);
}
2 changes: 1 addition & 1 deletion examples/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default async function Home() {
},
{
auth: {
clientId: process.env.GODADDY_CLIENT_ID || '',
clientId: process.env.NEXT_PUBLIC_GODADDY_CLIENT_ID || '',
clientSecret: process.env.GODADDY_CLIENT_SECRET || '',
},
}
Expand Down
31 changes: 28 additions & 3 deletions examples/nextjs/app/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
'use client';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { GoDaddyProvider } from '@godaddy/react';
import { QueryClient } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import Link from 'next/link';
import { useState } from 'react';

export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(() => new QueryClient());
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
retry: false,
refetchOnWindowFocus: false,
},
},
})
);

return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
<GoDaddyProvider
queryClient={queryClient}
apiHost={process.env.NEXT_PUBLIC_GODADDY_API_HOST}
storeId={process.env.NEXT_PUBLIC_GODADDY_STORE_ID}
clientId={process.env.NEXT_PUBLIC_GODADDY_CLIENT_ID}
Link={Link}
appearance={{
variables: { primary: '#ff0000', 'primary-foreground': '#FFFFFF' },
}}
>
{children}
<ReactQueryDevtools client={queryClient} initialIsOpen={false} />
</GoDaddyProvider>
);
}
62 changes: 62 additions & 0 deletions examples/nextjs/app/store/cart/cart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import { CartLineItems, CartTotals } from '@godaddy/react';

export default function CartPage() {
const items = [
{
id: 'LineItem_2y0l7o6Oi4BW6fpSiKPX1hhBccU',
name: 'Box of cookies',
image:
'https://isteam.dev-wsimg.com/ip/2f2e05ec-de6f-4a89-90f2-038c749655b0/cookies.webp',
quantity: 2,
originalPrice: 10.99,
price: 10.99,
notes: [],
},
{
id: 'LineItem_2y0l9FykA04qp2pC6y3YZ0TbZFD',
name: 'Cupcakes',
image:
'https://isteam.dev-wsimg.com/ip/2f2e05ec-de6f-4a89-90f2-038c749655b0/cupcakes.webp/:/rs=w:600,h:600',
quantity: 1,
originalPrice: 5.99,
price: 5.99,
notes: [],
},
];

const totals = {
subtotal: 27.97,
discount: 0,
shipping: 0,
currency: 'USD',
itemCount: 3,
total: 27.97,
tip: 0,
taxes: 0,
enableDiscounts: false,
enableTaxes: true,
isTaxLoading: false,
};

return (
<div className='container px-4 py-8'>
<h1 className='text-2xl font-bold mb-6'>Cart</h1>
<div className='grid grid-cols-1 gap-8'>
<div>
<div className='bg-white rounded-lg shadow p-6'>
<h2 className='text-lg font-semibold mb-4'>Your Items</h2>
<CartLineItems items={items} />
</div>
</div>
<div>
<div className='bg-white rounded-lg shadow p-6 sticky top-4'>
<h2 className='text-lg font-semibold mb-4'>Order Summary</h2>
<CartTotals {...totals} />
</div>
</div>
</div>
</div>
);
}
9 changes: 9 additions & 0 deletions examples/nextjs/app/store/cart/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Cart from './cart';

export default function StorePage() {
return (
<div className='p-4'>
<Cart />
</div>
);
}
52 changes: 52 additions & 0 deletions examples/nextjs/app/store/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client';

import { Cart } from '@godaddy/react';
import { ShoppingCart } from 'lucide-react';
import { createContext, useContext, useState } from 'react';

interface CartContextType {
openCart: () => void;
closeCart: () => void;
}

const CartContext = createContext<CartContextType | undefined>(undefined);

export function useCart() {
const context = useContext(CartContext);
if (!context) {
throw new Error('useCart must be used within CartProvider');
}
return context;
}

export default function StoreLayout({
children,
}: {
children: React.ReactNode;
}) {
const [isCartOpen, setIsCartOpen] = useState(false);

const openCart = () => setIsCartOpen(true);
const closeCart = () => setIsCartOpen(false);

return (
<CartContext.Provider value={{ openCart, closeCart }}>
<section className='relative max-w-6xl mx-auto'>
{/* Cart toggle button */}
<button
onClick={openCart}
className='fixed top-4 right-4 z-40 bg-primary text-primary-foreground p-3 rounded-full shadow-lg hover:bg-primary/90 transition-colors'
aria-label='Open shopping cart'
>
<ShoppingCart className='h-6 w-6' />
</button>

{children}

<Cart open={isCartOpen} onOpenChange={setIsCartOpen} />
</section>
</CartContext.Provider>
);
}

export { CartContext };
9 changes: 9 additions & 0 deletions examples/nextjs/app/store/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Products from './products';

export default function StorePage() {
return (
<div className='p-4'>
<Products />
</div>
);
}
18 changes: 18 additions & 0 deletions examples/nextjs/app/store/product/[productId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client';

import { use } from 'react';
import Product from '@/app/store/product/[productId]/product';

export default function ProductPage({
params,
}: {
params: Promise<{ productId: string }>;
}) {
const { productId } = use(params);

return (
<div className='p-4'>
<Product productId={productId} />
</div>
);
}
20 changes: 20 additions & 0 deletions examples/nextjs/app/store/product/[productId]/product.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client';

import { ProductDetails } from '@godaddy/react';
import { ArrowLeft } from 'lucide-react';
import Link from 'next/link';

export default function Product({ productId }: { productId: string }) {
return (
<div className='container mx-auto'>
<Link
href='/store'
className='inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors mb-6'
>
<ArrowLeft className='h-4 w-4' />
Back to Store
</Link>
<ProductDetails productId={productId} />
</div>
);
}
11 changes: 11 additions & 0 deletions examples/nextjs/app/store/products.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use client';

import { ProductGrid } from '@godaddy/react';

export default function ProductsPage() {
return (
<div className='container mx-auto'>
<ProductGrid getProductHref={sku => `/store/product/${sku}`} />
</div>
);
}
61 changes: 31 additions & 30 deletions examples/nextjs/package.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
{
"name": "nextjs",
"version": "0.1.1",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "biome check .",
"lint:fix": "biome check --write --unsafe ."
},
"dependencies": {
"@godaddy/localizations": "workspace:*",
"@godaddy/react": "workspace:*",
"@tanstack/react-query": "^5.66.0",
"@tanstack/react-query-devtools": "^5.76.1",
"next": "16.0.1",
"react": "19.2.0",
"react-dom": "19.2.0",
"zod": "^3.24.1"
},
"devDependencies": {
"@biomejs/biome": "^2",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"biome-config-godaddy": "workspace:*",
"tailwindcss": "^4",
"typescript": "^5"
}
"name": "nextjs",
"version": "0.1.1",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "biome check .",
"lint:fix": "biome check --write --unsafe ."
},
"dependencies": {
"@godaddy/localizations": "workspace:*",
"@godaddy/react": "workspace:*",
"@tanstack/react-query": "^5.66.0",
"@tanstack/react-query-devtools": "^5.76.1",
"lucide-react": "^0.475.0",
"next": "16.0.1",
"react": "19.2.0",
"react-dom": "19.2.0",
"zod": "^3.24.1"
},
"devDependencies": {
"@biomejs/biome": "^2",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"biome-config-godaddy": "workspace:*",
"tailwindcss": "^4",
"typescript": "^5"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-mocha": "^10.5.0",
"eslint-plugin-react": "^7.37.5",
"react": "^19.1.0",
"react": "^19.2.0",
"rimraf": "^6.0.1",
"typescript": "^5.8.3"
},
Expand Down
3 changes: 1 addition & 2 deletions packages/react/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": "gd"
"cssVariables": true
},
"aliases": {
"components": "@/components",
Expand Down
Loading