diff --git a/src/app/(main)/products/[slug]/page.tsx b/src/app/(main)/products/[slug]/page.tsx
index 8d6c8798a..0101245b9 100644
--- a/src/app/(main)/products/[slug]/page.tsx
+++ b/src/app/(main)/products/[slug]/page.tsx
@@ -145,7 +145,9 @@ export default async function Page(props: { params: { slug: string }; searchPara
: ""}
- {variants &&
diff --git a/src/graphql/ProductDetails.graphql b/src/graphql/ProductDetails.graphql
index 269bfd7e8..376470fb7 100644
--- a/src/graphql/ProductDetails.graphql
+++ b/src/graphql/ProductDetails.graphql
@@ -15,17 +15,7 @@ query ProductDetails($slug: String!) {
name
}
variants {
- id
- name
- quantityAvailable
- pricing {
- price {
- gross {
- currency
- amount
- }
- }
- }
+ ...VariantDetails
}
}
}
diff --git a/src/graphql/VariantDetailsFragment.graphql b/src/graphql/VariantDetailsFragment.graphql
new file mode 100644
index 000000000..0ee45fd01
--- /dev/null
+++ b/src/graphql/VariantDetailsFragment.graphql
@@ -0,0 +1,13 @@
+fragment VariantDetails on ProductVariant {
+ id
+ name
+ quantityAvailable
+ pricing {
+ price {
+ gross {
+ currency
+ amount
+ }
+ }
+ }
+}
diff --git a/src/ui/components/VariantSelector.tsx b/src/ui/components/VariantSelector.tsx
index 68c0196ab..2c380788d 100644
--- a/src/ui/components/VariantSelector.tsx
+++ b/src/ui/components/VariantSelector.tsx
@@ -1,45 +1,20 @@
-"use client";
-
import { clsx } from "clsx";
-import { usePathname, useRouter, useSearchParams } from "next/navigation";
-import { useCallback, useEffect } from "react";
-
-export const createPathname = (pathname: string, params: URLSearchParams) => {
- const paramsString = params.toString();
- const queryString = `${paramsString.length ? "?" : ""}${paramsString}`;
-
- return `${pathname}${queryString}`;
-};
-
-export function VariantSelector(props: {
- variants: { id: string; name: string; quantityAvailable?: number | null }[];
+import Link from "next/link";
+import { redirect } from "next/navigation";
+import { type ProductListItemFragment, type VariantDetailsFragment } from "@/gql/graphql";
+
+export function VariantSelector({
+ variants,
+ product,
+ selectedVariant,
+}: {
+ variants: readonly VariantDetailsFragment[];
+ product: ProductListItemFragment;
+ selectedVariant?: VariantDetailsFragment;
}) {
- const { variants } = props;
-
- const router = useRouter();
- const pathname = usePathname();
- const searchParams = useSearchParams();
-
- const selectVariant = useCallback(
- (variantID: string, replace = false) => {
- const params = new URLSearchParams(searchParams);
- params.set("variant", variantID);
-
- const variantPathname = createPathname(pathname, params);
- if (replace) {
- router.replace(variantPathname, { scroll: false });
- } else {
- router.push(variantPathname, { scroll: false });
- }
- },
- [pathname, router, searchParams],
- );
-
- useEffect(() => {
- if (variants.length === 1 && variants[0].quantityAvailable) {
- selectVariant(variants[0].id, true);
- }
- }, [selectVariant, variants]);
+ if (!selectedVariant && variants.length === 1 && variants[0]?.quantityAvailable) {
+ redirect(getHrefForVariant(product, variants[0]));
+ }
return (
);
}
+
+function getHrefForVariant(product: ProductListItemFragment, variant: VariantDetailsFragment): string {
+ const pathname = `/products/${encodeURIComponent(product.slug)}`;
+ const query = new URLSearchParams({ variant: variant.id });
+ return `${pathname}?${query.toString()}`;
+}