GraphQL Code Generator Hydrogen plugin #177
Replies: 3 comments 1 reply
-
This is a super cool idea. We use this strategy for our larger React apps here at Shopify. We've discussed adding this to our Hydrogen starter template before, and we ultimately decided against it. While it is nice and terse, it adds another layer of indirection: developers need to learn a new convention of importing a That said, there's nothing right now preventing a developer from doing this in their own Hydrogen apps! There might even be some cool graphql parsing plugins for Vite. Interested to see examples if folks find them. |
Beta Was this translation helpful? Give feedback.
-
I wound up making a plugin for our usage of Hydrogen based on the apollo-client plugin. It's by no means open-source ready (it has a ton of hardcoded config assumptions), but figured I'd share in case y'all do want to build one someday. Here's the gist. Generated code looks like this (clipped some stuff out for size): import { gql, useShopQuery } from '@shopify/hydrogen';
import * as Types from '@shopify/hydrogen/storefront-api-types';
type UseShopQueryBaseParams = Omit<Parameters<typeof useShopQuery>[0], 'variables' | 'query'>;
export type SearchProductsQueryVariables = Types.Exact<{
searchTerm: Types.InputMaybe<Types.Scalars['String']>;
country: Types.InputMaybe<Types.CountryCode>;
language: Types.InputMaybe<Types.LanguageCode>;
pageBy: Types.Scalars['Int'];
after: Types.InputMaybe<Types.Scalars['String']>;
}>;
export type SearchProductsQuery = {
__typename?: 'QueryRoot';
products: {
__typename?: 'ProductConnection';
nodes: Array<{ __typename?: 'Product' } & ProductCardFragment>;
};
};
export const SearchProductsDocument = gql`
query SearchProducts(
$searchTerm: String
$country: CountryCode
$language: LanguageCode
$pageBy: Int!
$after: String
) @inContext(country: $country, language: $language) {
products(first: $pageBy, sortKey: RELEVANCE, query: $searchTerm, after: $after) {
nodes {
...ProductCard
}
}
}
${ProductCardFragmentDoc}
`;
export function useSearchProductsShopQuery(
options: UseShopQueryBaseParams & { variables: SearchProductsQueryVariables }
) {
return useShopQuery<SearchProductsQuery>({ ...options, query: SearchProductsDocument });
} And this is our overwrite: true
schema: 'schema.graphql'
documents: ['src/**/*.graphql', 'src/*.graphql']
generates:
src/graphql/hooks.generated.ts:
preset: import-types
presetConfig:
typesPath: '@shopify/hydrogen/storefront-api-types'
plugins:
- 'typescript-operations':
avoidOptionals: true
exportFragmentSpreadSubTypes: true
inlineFragmentTypes: combine
- './bin/shop-query-gql-codegen/dist/index.js' |
Beta Was this translation helpful? Give feedback.
-
Our approach to solving this was to use the Here's an example snippet. You can assume here that we've already gotten Page.graphql query Page {
# ...Page fields from our CMS
} useCMSPageQuery.ts import { useQuery } from "@shopify/hydrogen";
import { GraphQLClient } from "graphql-request";
import { getSdk } from "./client.generated";
export default function useCMSPageQuery(id: string) {
const client = getSdk(
new GraphQLClient(Oxygen.env.CMS_ENDPOINT, {
headers: {
authorization: `Bearer ${Oxygen.env.CMS_ACCESS_TOKEN}`,
},
})
);
const { data, error } = useQuery(`useCMSPageQuery-id=${id}`, () => {
return client.Page({ id });
});
if (error) {
return {
error,
};
}
return { data };
} One thing that's import to remember: you need to ensure that the cache key is unique to both the SDK query function and all arguments otherwise you risk caching the wrong data. We're also planning on using this approach to query the Shopify Storefront API, given the lack of a plugin for GraphQL Code Generator. If you take this approach, ensure you account for rate limiting (see: #1883). |
Beta Was this translation helpful? Give feedback.
-
A GraphQL Code Generator Hydrogen plugin should improve DX and velocity.
In
useShopQuery
documentation example, the React Server Component code could be reduced to:With the following
blog.graphql
or (.js files usinggql
)A similar implementation can be find with React Query + graphql-request plugin
This solution makes React Server Components leaner with a nice separation of concerns, with a blazing fast code generations with Typescript Types 🚀
Beta Was this translation helpful? Give feedback.
All reactions