Template
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F22Ms5Cxam5UHyxaCrtZzu
160 lines
3.8 KiB
TypeScript
160 lines
3.8 KiB
TypeScript
import { gql } from "@shopify/hydrogen";
|
|
|
|
import { COLLECTION_CARD_FRAGMENT, PRODUCT_CARD_FRAGMENT } from "./fragments";
|
|
|
|
/**
|
|
* Home query — best-selling products (first 8) + featured collections (first 3).
|
|
* Used by the home page (`hydrogen-setup` / `references/home-page.md`).
|
|
*/
|
|
export const HOME_QUERY = gql(
|
|
`
|
|
query Home($country: CountryCode, $language: LanguageCode)
|
|
@inContext(country: $country, language: $language) {
|
|
featuredProducts: products(first: 8, sortKey: BEST_SELLING) {
|
|
nodes {
|
|
...ProductCard
|
|
}
|
|
}
|
|
featuredCollections: collections(first: 3) {
|
|
nodes {
|
|
...CollectionCard
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
[PRODUCT_CARD_FRAGMENT, COLLECTION_CARD_FRAGMENT],
|
|
);
|
|
|
|
/** Collections index query (`collections(first: 24)`). */
|
|
export const COLLECTIONS_QUERY = gql(
|
|
`
|
|
query CollectionsList($first: Int!, $after: String, $country: CountryCode, $language: LanguageCode)
|
|
@inContext(country: $country, language: $language) {
|
|
collections(first: $first, after: $after) {
|
|
pageInfo {
|
|
hasNextPage
|
|
endCursor
|
|
}
|
|
nodes {
|
|
...CollectionCard
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
[COLLECTION_CARD_FRAGMENT],
|
|
);
|
|
|
|
/**
|
|
* Collection PLP query. `filters` and `sortKey`/`reverse` come from
|
|
* `parseCollectionParams`. The `__typename` discipline is on `ProductCard`
|
|
* (no unions here).
|
|
*/
|
|
export const COLLECTION_QUERY = gql(
|
|
`
|
|
query Collection($handle: String!, $first: Int!, $after: String, $sortKey: ProductCollectionSortKeys, $reverse: Boolean, $filters: [ProductFilter!], $country: CountryCode, $language: LanguageCode)
|
|
@inContext(country: $country, language: $language) {
|
|
collection(handle: $handle) {
|
|
id
|
|
handle
|
|
title
|
|
description
|
|
descriptionHtml
|
|
image {
|
|
url
|
|
altText
|
|
width
|
|
height
|
|
}
|
|
products(first: $first, after: $after, sortKey: $sortKey, reverse: $reverse, filters: $filters) {
|
|
filters {
|
|
id
|
|
label
|
|
type
|
|
values {
|
|
id
|
|
label
|
|
count
|
|
input
|
|
}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
endCursor
|
|
}
|
|
nodes {
|
|
...ProductCard
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
[PRODUCT_CARD_FRAGMENT],
|
|
);
|
|
|
|
/**
|
|
* Search query. **`__typename` on `search.nodes` is required** — `search` is a
|
|
* heterogeneous union and without `__typename` gql.tada infers `never` for the
|
|
* node type and all results are dropped (feedback Round 1 + Round 2 #1).
|
|
*/
|
|
export const SEARCH_QUERY = gql(
|
|
`
|
|
query Search($query: String!, $first: Int!, $after: String, $sortKey: SearchSortKeys, $reverse: Boolean, $productFilters: [ProductFilter!], $country: CountryCode, $language: LanguageCode)
|
|
@inContext(country: $country, language: $language) {
|
|
search(query: $query, first: $first, after: $after, sortKey: $sortKey, reverse: $reverse, productFilters: $productFilters) {
|
|
productFilters {
|
|
id
|
|
label
|
|
type
|
|
values {
|
|
id
|
|
label
|
|
count
|
|
input
|
|
}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
endCursor
|
|
}
|
|
nodes {
|
|
__typename
|
|
... on Product {
|
|
...ProductCard
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
[PRODUCT_CARD_FRAGMENT],
|
|
);
|
|
|
|
/** Shop analytics GID query (root layout, best-effort + non-blocking, F1). */
|
|
export const SHOP_ANALYTICS_QUERY = gql(`
|
|
query RootShopAnalytics {
|
|
shop {
|
|
id
|
|
name
|
|
description
|
|
}
|
|
}
|
|
`);
|
|
|
|
/** Sitemap query — all products + collections with `updatedAt`. */
|
|
export const SITEMAP_QUERY = gql(`
|
|
query Sitemap($country: CountryCode, $language: LanguageCode)
|
|
@inContext(country: $country, language: $language) {
|
|
products(first: 250) {
|
|
nodes {
|
|
handle
|
|
updatedAt
|
|
}
|
|
}
|
|
collections(first: 250) {
|
|
nodes {
|
|
handle
|
|
updatedAt
|
|
}
|
|
}
|
|
}
|
|
`);
|