Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use lang directive #1028

Merged
merged 12 commits into from
Apr 5, 2022
12 changes: 12 additions & 0 deletions .changeset/hungry-scissors-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@shopify/hydrogen': minor
'create-hydrogen-app': minor
---

Starting from SF API version `2022-04`, the preferred way to request translatable resources is using the `@inContext` directive. See the [API docs](https://shopify.dev/api/examples/multiple-languages#retrieve-translations-with-the-storefront-api) on how to do this and which resources have translatable properties.

This causes a breaking change to the `useShopQuery` hook. The `locale` property has been removed from the argument object; `Accept-Language` is no longer being send with every request, and we are no longer using locale as part of the cache key.

The `useShop` hook will now return the `languageCode` key, which is the first two characters of the existing `locale` key.

Both `locale` & `languageCode` values are also now capitalized to make it easier to pass into a GraphQL `@inContext` directive.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
useShop,
useShopQuery,
flattenConnection,
LocalizationProvider,
Expand All @@ -15,9 +16,12 @@ import {Suspense} from 'react';
* A server component that defines a structure and organization of a page that can be used in different parts of the Hydrogen app
*/
export default function Layout({children, hero}) {
const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {
language: languageCode,
numCollections: 3,
},
cache: CacheHours(),
Expand Down Expand Up @@ -56,7 +60,8 @@ export default function Layout({children, hero}) {
}

const QUERY = gql`
query layoutContent($numCollections: Int!) {
query layoutContent($language: LanguageCode, $numCollections: Int!)
@inContext(language: $language) {
shop {
name
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useShopQuery, flattenConnection} from '@shopify/hydrogen';
import {useShop, useShopQuery, flattenConnection} from '@shopify/hydrogen';
import gql from 'graphql-tag';

import Layout from './Layout.server';
Expand Down Expand Up @@ -35,10 +35,13 @@ export default function NotFound({country = {isoCode: 'US'}, response}) {
response.writeHead({status: 404, statusText: 'Not found'});
}

const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {
country: country.isoCode,
language: languageCode,
},
});
const products = data ? flattenConnection(data.products) : [];
Expand All @@ -63,8 +66,8 @@ export default function NotFound({country = {isoCode: 'US'}, response}) {
}

const QUERY = gql`
query NotFoundProductDetails($country: CountryCode)
@inContext(country: $country) {
query NotFoundProductDetails($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
products(first: 3) {
edges {
node {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import {useShopQuery, flattenConnection, Link} from '@shopify/hydrogen';
import {
useShop,
useShopQuery,
flattenConnection,
Link,
} from '@shopify/hydrogen';
import gql from 'graphql-tag';
import {Suspense} from 'react';

Expand Down Expand Up @@ -39,7 +44,13 @@ function BoxFallback() {
}

function StorefrontInfo() {
const {data} = useShopQuery({query: QUERY, preload: true});
const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {language: languageCode},
preload: true,
});
const shopName = data ? data.shop.name : '';
const products = data && flattenConnection(data.products);
const collections = data && flattenConnection(data.collections);
Expand Down Expand Up @@ -86,7 +97,13 @@ function StorefrontInfo() {
}

function TemplateLinks() {
const {data} = useShopQuery({query: QUERY, preload: true});
const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {language: languageCode},
preload: true,
});
const products = data && flattenConnection(data.products);
const collections = data && flattenConnection(data.collections);

Expand Down Expand Up @@ -166,7 +183,8 @@ export default function Welcome() {
}

const QUERY = gql`
query welcomeContent {
query welcomeContent($language: LanguageCode)
@inContext(language: $language) {
shop {
name
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useShopQuery, flattenConnection, Seo} from '@shopify/hydrogen';
import {useShop, useShopQuery, flattenConnection, Seo} from '@shopify/hydrogen';
import gql from 'graphql-tag';

import LoadMoreProducts from '../../components/LoadMoreProducts.client';
Expand All @@ -11,12 +11,15 @@ export default function Collection({
collectionProductCount = 24,
params,
}) {
const {languageCode} = useShop();

const {handle} = params;
const {data} = useShopQuery({
query: QUERY,
variables: {
handle,
country: country.isoCode,
language: languageCode,
numProducts: collectionProductCount,
},
preload: true,
Expand Down Expand Up @@ -62,8 +65,9 @@ const QUERY = gql`
query CollectionDetails(
$handle: String!
$country: CountryCode
$language: LanguageCode
$numProducts: Int!
) @inContext(country: $country) {
) @inContext(country: $country, language: $language) {
collection(handle: $handle) {
title
descriptionHtml
Expand Down
10 changes: 9 additions & 1 deletion examples/template-hydrogen-default/src/routes/index.server.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
useShop,
useShopQuery,
flattenConnection,
Link,
Expand Down Expand Up @@ -59,10 +60,13 @@ function BoxFallback() {
}

function FeaturedProductsBox({country}) {
const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {
country: country.isoCode,
language: languageCode,
},
preload: true,
});
Expand Down Expand Up @@ -112,10 +116,13 @@ function FeaturedProductsBox({country}) {
}

function FeaturedCollectionBox({country}) {
const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {
country: country.isoCode,
language: languageCode,
},
preload: true,
});
Expand Down Expand Up @@ -191,7 +198,8 @@ const SEO_QUERY = gql`
`;

const QUERY = gql`
query indexContent($country: CountryCode) @inContext(country: $country) {
query indexContent($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
collections(first: 2) {
edges {
node {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import {useShopQuery, Seo} from '@shopify/hydrogen';
import {useShop, useShopQuery, Seo} from '@shopify/hydrogen';
import gql from 'graphql-tag';

import Layout from '../../components/Layout.server';
import NotFound from '../../components/NotFound.server';

export default function Page({params}) {
const {languageCode} = useShop();

const {handle} = params;
const {data} = useShopQuery({query: QUERY, variables: {handle}});
const {data} = useShopQuery({
query: QUERY,
variables: {language: languageCode, handle},
});

if (!data.pageByHandle) {
return <NotFound />;
Expand All @@ -27,7 +32,8 @@ export default function Page({params}) {
}

const QUERY = gql`
query PageDetails($handle: String!) {
query PageDetails($language: LanguageCode, $handle: String!)
@inContext(language: $language) {
pageByHandle(handle: $handle) {
title
body
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useShopQuery, Seo, useRouteParams} from '@shopify/hydrogen';
import {useShop, useShopQuery, Seo, useRouteParams} from '@shopify/hydrogen';
import gql from 'graphql-tag';

import ProductDetails from '../../components/ProductDetails.client';
Expand All @@ -8,12 +8,15 @@ import Layout from '../../components/Layout.server';
export default function Product({country = {isoCode: 'US'}}) {
const {handle} = useRouteParams();

const {languageCode} = useShop();

const {
data: {product},
} = useShopQuery({
query: QUERY,
variables: {
country: country.isoCode,
language: languageCode,
handle,
},
preload: true,
Expand All @@ -32,8 +35,11 @@ export default function Product({country = {isoCode: 'US'}}) {
}

const QUERY = gql`
query product($country: CountryCode, $handle: String!)
@inContext(country: $country) {
query product(
$country: CountryCode
$language: LanguageCode
$handle: String!
) @inContext(country: $country, language: $language) {
product: product(handle: $handle) {
compareAtPriceRange {
maxVariantPrice {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {flattenConnection, useShopQuery} from '@shopify/hydrogen';
import {flattenConnection, useShopQuery, useShop} from '@shopify/hydrogen';
import gql from 'graphql-tag';

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

export default function Sitemap({request, response}) {
response.doNotStream();

const {languageCode} = useShop();

const {data} = useShopQuery({
query: QUERY,
variables: {
language: languageCode,
urlLimits: MAX_URLS,
},
// Cache the page for 24 hours
Expand Down Expand Up @@ -108,7 +111,8 @@ function renderUrlTag({url, lastMod, changeFreq, image}) {
}

const QUERY = gql`
query sitemaps($urlLimits: Int) {
query sitemaps($urlLimits: Int, $language: LanguageCode)
@inContext(language: $language) {
products(
first: $urlLimits
query: "published_status:'online_store:visible'"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {createContext} from 'react';
import {LocalizationQuery} from './LocalizationQuery';
import type {LocalizationQuery} from './LocalizationProvider.server';

export type Localization = LocalizationQuery['localization'];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, {ReactNode} from 'react';
import LocalizationClientProvider from './LocalizationClientProvider.client';
import {useShop} from '../../foundation/useShop';
import {useShopQuery} from '../../hooks/useShopQuery';
import {LocalizationQuery} from './LocalizationQuery';
import {CacheDays} from '../../framework/CachingStrategy';
import {PreloadOptions} from '../../types';
import {Country, Currency} from '../../storefront-api-types';

export interface LocalizationProviderProps {
/** A `ReactNode` element. */
Expand All @@ -25,10 +26,13 @@ export interface LocalizationProviderProps {
* `@inContext` directive as the `country` value.
*/
export function LocalizationProvider(props: LocalizationProviderProps) {
const {languageCode} = useShop();

const {
data: {localization},
} = useShopQuery<LocalizationQuery>({
query: query,
variables: {language: languageCode},
cache: CacheDays(),
preload: props.preload,
});
Expand All @@ -40,8 +44,18 @@ export function LocalizationProvider(props: LocalizationProviderProps) {
);
}

const query = `query Localization {
localization {
export type LocalizationQuery = {__typename?: 'QueryRoot'} & {
localization: {__typename?: 'Localization'} & {
country: {__typename?: 'Country'} & Pick<Country, 'isoCode' | 'name'> & {
currency: {__typename?: 'Currency'} & Pick<Currency, 'isoCode'>;
};
};
};

const query = `
query Localization($language: LanguageCode)
@inContext(language: $language) {
localization {
country {
isoCode
name
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export function DefaultPageSeo({
titleTemplate,
lang,
}: PartialDeep<DefaultPage>) {
const {locale} = useShop();
const fallBacklang = locale.split(/[-_]/)[0];
const {languageCode: fallBacklang} = useShop();

return (
<>
Expand Down
Loading