diff --git a/app/routes/products.$handle/route.jsx b/app/routes/products.$handle/route.jsx
index 4998fc7..ed2b495 100644
--- a/app/routes/products.$handle/route.jsx
+++ b/app/routes/products.$handle/route.jsx
@@ -1,101 +1,118 @@
import React from 'react'
-import {defer, redirect} from '@shopify/remix-oxygen';
-import {getSelectedProductOptions} from '@shopify/hydrogen';
-import {getVariantUrl} from '~/lib/variants';
-import Hero from './sections/hero';
-import HighlightDetails from './sections/highlight-details';
-import HighlightSolution from './sections/highlight-solution';
-import Reviews from './sections/reviews';
-import Spotlight from './sections/spotlight';
-import Recommended from './sections/recommended';
-import Marquee from './sections/marquee';
-import {Await, useLoaderData} from '@remix-run/react';
-import {Suspense} from 'react';
+import { defer, redirect } from '@shopify/remix-oxygen'
+import { getSelectedProductOptions } from '@shopify/hydrogen'
+import { getVariantUrl } from '~/lib/variants'
+import Hero from './sections/hero'
+import HighlightDetails from './sections/highlight-details'
+import HighlightSolution from './sections/highlight-solution'
+import Reviews from './sections/reviews'
+import Spotlight from './sections/spotlight'
+import Recommended from './sections/recommended'
+import Marquee from './sections/marquee'
+import { Await, useLoaderData } from '@remix-run/react'
+import { Suspense } from 'react'
-export const meta = ({data}) => {
- return [{title: `Builder Supply | ${data?.product.title ?? ''}`}];
-};
+export const meta = ({ data }) => {
+ return [
+ {
+ title: `Builder Supply | ${
+ data?.product.title ?? ''
+ }`,
+ },
+ ]
+}
export async function loader(args) {
return defer({
...(await primaryData(args)),
...secondaryData(args),
- });
+ })
}
/**
* Load data necessary for rendering content above the fold. This is the primary data
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
*/
-async function primaryData({context, params, request}) {
- const {handle} = params;
- const {storefront} = context;
+async function primaryData({ context, params, request }) {
+ const { handle } = params
+ const { storefront } = context
if (!handle) {
- throw new Error('Expected product handle to be defined');
+ throw new Error('Expected product handle to be defined')
}
- const [{product}, {details}] = await Promise.all([
+ const [{ product }, { details }] = await Promise.all([
storefront.query(PRODUCT_QUERY, {
- variables: {handle, selectedOptions: getSelectedProductOptions(request)},
+ variables: {
+ handle,
+ selectedOptions: getSelectedProductOptions(request),
+ },
}),
// Add other queries here, so that they are loaded in parallel
storefront.query(DETAILS_QUERY, {
- variables: {handle},
+ variables: { handle },
}),
- ]);
+ ])
if (!product?.id) {
- throw new Response(null, {status: 404});
+ throw new Response(null, { status: 404 })
}
- const firstVariant = product.variants.nodes[0];
+ const firstVariant = product.variants.nodes[0]
const firstVariantIsDefault = Boolean(
firstVariant.selectedOptions.find(
- (option) => option.name === 'Title' && option.value === 'Default Title',
+ (option) =>
+ option.name === 'Title' &&
+ option.value === 'Default Title',
),
- );
+ )
if (firstVariantIsDefault) {
- product.selectedVariant = firstVariant;
+ product.selectedVariant = firstVariant
} else {
// if no selected variant was returned from the selected options,
// we redirect to the first variant's url with it's selected options applied
if (!product.selectedVariant) {
- throw redirectToFirstVariant({product, request});
+ throw redirectToFirstVariant({ product, request })
}
}
return {
product,
details,
- };
+ }
}
/**
* Load data for rendering content below the fold. This data is deferred and will be
* fetched after the initial page load. If it's unavailable, the page should still 200.
*/
-function secondaryData({context: {storefront}, params: {handle}}) {
+function secondaryData({
+ context: { storefront },
+ params: { handle },
+}) {
const variants = storefront.query(VARIANTS_QUERY, {
- variables: {handle},
- });
+ variables: { handle },
+ })
const solution = storefront.query(SOLUTION_QUERY, {
- variables: {handle},
- });
+ variables: { handle },
+ })
const reviews = storefront.query(REVIEWS_QUERY, {
- variables: {handle},
- });
+ variables: { handle },
+ })
- const relatedProducts = storefront.query(RELATED_PRODUCTS_QUERY, {
- variables: {handle},
- });
+ const relatedProducts = storefront.query(
+ RELATED_PRODUCTS_QUERY,
+ {
+ variables: { handle },
+ },
+ )
const spotlight = storefront.query(SPOTLIGHT_QUERY, {
- variables: {handle},
- });
+ variables: { handle },
+ })
return {
variants,
@@ -103,12 +120,12 @@ function secondaryData({context: {storefront}, params: {handle}}) {
reviews,
relatedProducts,
spotlight,
- };
+ }
}
-function redirectToFirstVariant({product, request}) {
- const url = new URL(request.url);
- const firstVariant = product.variants.nodes[0];
+function redirectToFirstVariant({ product, request }) {
+ const url = new URL(request.url)
+ const firstVariant = product.variants.nodes[0]
return redirect(
getVariantUrl({
@@ -120,40 +137,54 @@ function redirectToFirstVariant({product, request}) {
{
status: 302,
},
- );
+ )
}
export default function Product() {
- const {solution, reviews, relatedProducts, spotlight} = useLoaderData();
+ const { solution, reviews, relatedProducts, spotlight } =
+ useLoaderData()
return (
<>
-
-
+
+
{(data) => (
-
+
)}
-
- {(data) => }
+
+
+ {(data) => }
+
-
-
+
+
{(data) => (
-
+
)}
-
-
- {(data) => }
+
+
+ {(data) => (
+
+ )}
>
- );
+ )
}
/***********************
@@ -195,7 +226,7 @@ const PRODUCT_VARIANT_FRAGMENT = `#graphql
currencyCode
}
}
-`;
+`
const PRODUCT_FRAGMENT = `#graphql
fragment Product on Product {
@@ -235,7 +266,7 @@ const PRODUCT_FRAGMENT = `#graphql
}
}
${PRODUCT_VARIANT_FRAGMENT}
-`;
+`
const DETAILS_QUERY = `#graphql
query Details(
@@ -266,7 +297,7 @@ query Details(
}
}
}
-}`;
+}`
const SOLUTION_QUERY = `#graphql
query Solution(
@@ -291,7 +322,7 @@ query Solution(
}
}
}
-}`;
+}`
const REVIEWS_QUERY = `#graphql
query Reviews(
@@ -322,7 +353,7 @@ query Reviews(
}
}
}
-}`;
+}`
const RELATED_PRODUCTS_QUERY = `#graphql
query RelatedProducts(
@@ -365,7 +396,7 @@ query RelatedProducts(
}
}
}
-}`;
+}`
const SPOTLIGHT_QUERY = `#graphql
query Spotlight(
@@ -430,7 +461,7 @@ query Spotlight(
}
}
}
-}`;
+}`
const PRODUCT_QUERY = `#graphql
query Product(
@@ -444,7 +475,7 @@ const PRODUCT_QUERY = `#graphql
}
}
${PRODUCT_FRAGMENT}
-`;
+`
const PRODUCT_VARIANTS_FRAGMENT = `#graphql
fragment ProductVariants on Product {
@@ -455,7 +486,7 @@ const PRODUCT_VARIANTS_FRAGMENT = `#graphql
}
}
${PRODUCT_VARIANT_FRAGMENT}
-`;
+`
const VARIANTS_QUERY = `#graphql
query ProductVariants(
@@ -468,7 +499,7 @@ const VARIANTS_QUERY = `#graphql
}
}
${PRODUCT_VARIANTS_FRAGMENT}
-`;
+`
/** @typedef {import('@shopify/remix-oxygen').LoaderFunctionArgs} LoaderFunctionArgs */
/** @template T @typedef {import('@remix-run/react').MetaFunction} MetaFunction */