Skip to content

Commit

Permalink
Migrate pages to context.storefront.query (Shopify#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
blittle authored Nov 1, 2022
1 parent a53730b commit 801c78d
Show file tree
Hide file tree
Showing 14 changed files with 824 additions and 996 deletions.
875 changes: 3 additions & 872 deletions app/data/index.ts

Large diffs are not rendered by default.

103 changes: 85 additions & 18 deletions app/routes/[sitemap.xml].tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,49 @@
import type {LoaderArgs} from '@hydrogen/remix';
import {flattenConnection} from '@shopify/hydrogen-react';
import {getSitemap} from '~/data';
import type {LoaderArgs} from '@hydrogen/remix';
import {
CollectionConnection,
PageConnection,
ProductConnection,
} from '@shopify/hydrogen-react/storefront-api-types';
import invariant from 'tiny-invariant';
import {getLocalizationFromLang} from '~/lib/utils';

const MAX_URLS = 250; // the google limit is 50K, however, SF API only allow querying for 250 resources each time

export async function loader({request, params}: LoaderArgs) {
const data = await getSitemap({
params,
urlLimits: MAX_URLS,
interface SitemapQueryData {
products: ProductConnection;
collections: CollectionConnection;
pages: PageConnection;
}

interface ProductEntry {
url: string;
lastMod: string;
changeFreq: string;
image?: {
url: string;
title?: string;
caption?: string;
};
}

export async function loader({
request,
params,
context: {storefront},
}: LoaderArgs) {
const {language} = getLocalizationFromLang(params.lang);

const data = await storefront.query<SitemapQueryData>({
query: SITEMAP_QUERY,
variables: {
language,
urlLimits: MAX_URLS,
},
});

invariant(data, 'Sitemap data is missing');

return new Response(
shopSitemap({data, baseUrl: new URL(request.url).origin}),
{
Expand All @@ -22,22 +56,11 @@ export async function loader({request, params}: LoaderArgs) {
);
}

interface ProductEntry {
url: string;
lastMod: string;
changeFreq: string;
image?: {
url: string;
title?: string;
caption?: string;
};
}

function shopSitemap({
data,
baseUrl,
}: {
data: Awaited<ReturnType<typeof getSitemap>>;
data: SitemapQueryData;
baseUrl: string;
}) {
const productsData = flattenConnection(data.products)
Expand Down Expand Up @@ -137,3 +160,47 @@ function renderUrlTag({
</url>
`;
}

const SITEMAP_QUERY = `#graphql
query sitemaps($urlLimits: Int, $language: LanguageCode)
@inContext(language: $language) {
products(
first: $urlLimits
query: "published_status:'online_store:visible'"
) {
edges {
node {
updatedAt
handle
onlineStoreUrl
title
featuredImage {
url
altText
}
}
}
}
collections(
first: $urlLimits
query: "published_status:'online_store:visible'"
) {
edges {
node {
updatedAt
handle
onlineStoreUrl
}
}
}
pages(first: $urlLimits, query: "published_status:'published'") {
edges {
node {
updatedAt
handle
onlineStoreUrl
}
}
}
}
`;
5 changes: 3 additions & 2 deletions app/routes/account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ import {
import {FeaturedCollections} from '~/components/FeaturedCollections';
import {type LoaderArgs, redirect, json, defer} from '@hydrogen/remix';
import {flattenConnection} from '@shopify/hydrogen-react';
import {getCustomer, getFeaturedData} from '~/data';
import {getCustomer} from '~/data';
import {getSession} from '~/lib/session.server';
import {getFeaturedData} from './featured-products';

export async function loader({request, context, params}: LoaderArgs) {
const {pathname} = new URL(request.url);
Expand Down Expand Up @@ -67,7 +68,7 @@ export async function loader({request, context, params}: LoaderArgs) {
heading,
orders,
addresses: flattenConnection(customer.addresses) as MailingAddress[],
featuredData: getFeaturedData({params}),
featuredData: getFeaturedData(context.storefront, params),
});
}

Expand Down
71 changes: 65 additions & 6 deletions app/routes/collections/$collectionHandle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,41 @@ import type {Collection as CollectionType} from '@shopify/hydrogen-react/storefr
import invariant from 'tiny-invariant';
import {PageHeader, Section, Text} from '~/components';
import {ProductGrid} from '~/components/ProductGrid';
import {getCollection} from '~/data';
import {getLocalizationFromLang} from '~/lib/utils';
import type {Collection} from '@shopify/hydrogen-react/storefront-api-types';
import {PRODUCT_CARD_FRAGMENT} from '~/data';

export async function loader({params, request}: LoaderArgs) {
const PAGINATION_SIZE = 48;

export async function loader({
params,
request,
context: {storefront},
}: LoaderArgs) {
const {collectionHandle} = params;

invariant(collectionHandle, 'Missing collectionHandle param');

const cursor = new URL(request.url).searchParams.get('cursor') ?? undefined;
const collection = await getCollection({
handle: collectionHandle,
cursor,
params,
const {language, country} = getLocalizationFromLang(params.lang);

const {collection} = await storefront.query<{
collection: Collection;
}>({
query: COLLECTION_QUERY,
variables: {
handle: collectionHandle,
pageBy: PAGINATION_SIZE,
cursor,
language,
country,
},
});

if (!collection) {
throw new Response('Not found', {status: 404});
}

return json({collection});
}

Expand Down Expand Up @@ -63,3 +84,41 @@ export default function Collection() {
</>
);
}

const COLLECTION_QUERY = `#graphql
${PRODUCT_CARD_FRAGMENT}
query CollectionDetails(
$handle: String!
$country: CountryCode
$language: LanguageCode
$pageBy: Int!
$cursor: String
) @inContext(country: $country, language: $language) {
collection(handle: $handle) {
id
handle
title
description
seo {
description
title
}
image {
id
url
width
height
altText
}
products(first: $pageBy, after: $cursor) {
nodes {
...ProductCard
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
`;
54 changes: 49 additions & 5 deletions app/routes/collections/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import {json, type LoaderArgs, type MetaFunction} from '@hydrogen/remix';
import {useLoaderData} from '@remix-run/react';
import type {Collection} from '@shopify/hydrogen-react/storefront-api-types';
import type {
Collection,
CollectionConnection,
} from '@shopify/hydrogen-react/storefront-api-types';
import {Grid, Heading, PageHeader, Section, Link} from '~/components';
import {getCollections} from '~/data';
import {getImageLoadingPriority} from '~/lib/const';
import {getLocalizationFromLang} from '~/lib/utils';

export const loader = async ({params}: LoaderArgs) => {
const collections = await getCollections(params);
const PAGINATION_SIZE = 8;

return json({collections});
export const loader = async ({params, context: {storefront}}: LoaderArgs) => {
const {language, country} = getLocalizationFromLang(params.lang);

const {collections} = await storefront.query<{
collections: CollectionConnection;
}>({
query: COLLECTIONS_QUERY,
variables: {
pageBy: PAGINATION_SIZE,
country,
language,
},
});

return json({collections: collections.nodes});
};

export const meta: MetaFunction = () => {
Expand Down Expand Up @@ -65,3 +81,31 @@ function CollectionCard({
</Link>
);
}

const COLLECTIONS_QUERY = `#graphql
query Collections(
$country: CountryCode
$language: LanguageCode
$pageBy: Int!
) @inContext(country: $country, language: $language) {
collections(first: $pageBy) {
nodes {
id
title
description
handle
seo {
description
title
}
image {
id
url
width
height
altText
}
}
}
}
`;
59 changes: 56 additions & 3 deletions app/routes/featured-products.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,59 @@
import {json, type LoaderArgs} from '@hydrogen/remix';
import {getFeaturedData} from '~/data';
import {flattenConnection} from '@shopify/hydrogen-react';
import type {
CollectionConnection,
ProductConnection,
} from '@shopify/hydrogen-react/storefront-api-types';
import invariant from 'tiny-invariant';
import {PRODUCT_CARD_FRAGMENT} from '~/data';
import {getLocalizationFromLang} from '~/lib/utils';

export async function loader({params}: LoaderArgs) {
return json(await getFeaturedData({params}));
export async function loader({params, context: {storefront}}: LoaderArgs) {
return json(await getFeaturedData(storefront, params));
}

export async function getFeaturedData(
storefront: LoaderArgs['context']['storefront'],
params: LoaderArgs['params'],
) {
const {language, country} = getLocalizationFromLang(params.lang);
const data = await storefront.query<{
featuredCollections: CollectionConnection;
featuredProducts: ProductConnection;
}>({
query: FEATURED_QUERY,
variables: {language, country},
});

invariant(data, 'No data returned from Shopify API');

return {
featuredCollections: flattenConnection(data.featuredCollections),
featuredProducts: flattenConnection(data.featuredProducts),
};
}

const FEATURED_QUERY = `#graphql
${PRODUCT_CARD_FRAGMENT}
query homepage($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
featuredCollections: collections(first: 3, sortKey: UPDATED_AT) {
nodes {
id
title
handle
image {
altText
width
height
url
}
}
}
featuredProducts: products(first: 12) {
nodes {
...ProductCard
}
}
}
`;
Loading

0 comments on commit 801c78d

Please sign in to comment.