Skip to main content

๐Ÿงพ getProduct() Overview

The getProduct() method allows you to fetch a single product by its handle or ID, along with associated variants, images, pricing, and custom metafields.

It returns a well-structured and typed result with a familiar shape you can use in your frontend โ€” without writing raw GraphQL.


โœ… When to use thisโ€‹

  • Rendering a product detail page
  • Getting variant-specific pricing
  • Displaying custom product attributes via metafields
  • Fetching product details for static generation or SSR

๐Ÿง  Basic Usageโ€‹

import { getProduct } from "@/lib/NextShopKit/client";

const { data, error } = await getProduct({
handle: "solar-kit-9kw",
customMetafields: [
{ field: "custom.warranty", type: "single_line_text" },
{ field: "custom.weight", type: "decimal" },
],
options: {
resolveFiles: true,
renderRichTextAsHtml: true,
camelizeKeys: true,
},
});

if (error || !data) {
// handle error
}

console.log(data.title, data.price.amount);

๐Ÿ“ฅ Input Sourcesโ€‹

You can fetch a product using:

  • โœ… handle (recommended for product pages)
  • โœ… id (if stored in your database or passed from related queries)

You must provide either handle or id. If both are missing, an error will be returned.


๐Ÿ“ฆ Returned Dataโ€‹

You receive a fully typed Product object containing:

  • id, title, handle, descriptionHtml
  • featuredImage, images[]
  • variants[] โ€” each with:
    • variantTitle, price, optional compareAtPrice
    • optional metafields
  • price, compareAtPrice โ€” inferred from the first variant
  • metafields โ€” casted, camelized, and optionally transformed

โžก๏ธ See full return structure in Result Types โ†’


๐Ÿงฉ Metafield Supportโ€‹

getProduct() supports:

  • customMetafields: for product-level metafields
  • variantMetafields: for metafields inside each variant

You can also:

  • Transform data using transformMetafields
  • Automatically cast and format files or rich text

โžก๏ธ Learn how to define and use metafields in Custom Metafields โ†’


๐Ÿ”’ Security & Usage Guidelinesโ€‹

Use private environment variables for optimal security and performance:

// Server Component, API route, or "use server" function
const { data, error } = await getProduct({ handle: "product-handle" });

โœ… Best for:

  • Product detail pages
  • Static generation and SSR
  • API routes and server actions
  • Better performance and SEO

โš›๏ธ Client-side Usage (When Required)โ€‹

Use NEXT_PUBLIC_ environment variables for interactive features:

// Client component (when needed for dynamic interactions)
import { useEffect, useState } from "react";

function DynamicProductComponent({ handle }) {
// Note: Consider server-side fetching for better performance
const [product, setProduct] = useState(null);

useEffect(() => {
// Fetch via API route instead of direct SDK call
fetch(`/api/products/${handle}`)
.then((res) => res.json())
.then(setProduct);
}, [handle]);
}
Recommendation

For product pages, prefer server-side fetching for better performance, SEO, and security. Use client-side approaches only when you need real-time updates or dynamic interactions.


โœ… Continue: Options Reference โ†’