Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
"encrypt": "ejson encrypt secrets.ejson",
"lint": "eslint --no-error-on-unmatched-pattern ./packages",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to add templates here as well, but i opted not to touch linting right now

"lint-staged": "eslint --no-error-on-unmatched-pattern",
"format": "prettier --write --ignore-unknown ./packages",
"format:check": "prettier --check --ignore-unknown ./packages",
"format": "prettier --write --ignore-unknown ./packages ./templates",
"format:check": "prettier --check --ignore-unknown ./packages ./templates",
"typecheck": "turbo typecheck --parallel",
"test": "turbo run test --parallel",
"test:watch": "turbo run test:watch",
Expand Down Expand Up @@ -106,7 +106,8 @@
"tiny-invariant": "^1.3.3",
"tsup": "^8.4.0",
"turbo": "2.8.9",
"typescript": "5.9.2"
"typescript": "5.9.2",
"@shopify/prettier-config": "catalog:"
},
"engines": {
"node": "^22 || ^24",
Expand Down
8 changes: 7 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ catalog:
'@types/react-dom': '^18.3.7'
react: '^18.3.1'
react-dom: '^18.3.1'
'@shopify/prettier-config': '^1.1.2'
5 changes: 2 additions & 3 deletions templates/skeleton/app/entry.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import {NonceProvider} from '@shopify/hydrogen';
if (!window.location.origin.includes('webcache.googleusercontent.com')) {
startTransition(() => {
// Extract nonce from existing script tags
const existingNonce = document
.querySelector<HTMLScriptElement>('script[nonce]')
?.nonce;
const existingNonce =
document.querySelector<HTMLScriptElement>('script[nonce]')?.nonce;

hydrateRoot(
document,
Expand Down
6 changes: 1 addition & 5 deletions templates/skeleton/app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
Await,
useLoaderData,
Link,
} from 'react-router';
import {Await, useLoaderData, Link} from 'react-router';
import type {Route} from './+types/_index';
import {Suspense} from 'react';
import {Image} from '@shopify/hydrogen';
Expand Down
11 changes: 4 additions & 7 deletions templates/skeleton/app/routes/account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ export function shouldRevalidate() {

export async function loader({context}: Route.LoaderArgs) {
const {customerAccount} = context;
const {data, errors} = await customerAccount.query(
CUSTOMER_DETAILS_QUERY,
{
variables: {
language: customerAccount.i18n.language,
},
const {data, errors} = await customerAccount.query(CUSTOMER_DETAILS_QUERY, {
variables: {
language: customerAccount.i18n.language,
},
);
});

if (errors?.length || !data?.customer) {
throw new Error('Customer not found');
Expand Down
11 changes: 2 additions & 9 deletions templates/skeleton/app/routes/blogs.$blogHandle._index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
Link,
useLoaderData,
} from 'react-router';
import {Link, useLoaderData} from 'react-router';
import type {Route} from './+types/blogs.$blogHandle._index';
import {Image, getPaginationVariables} from '@shopify/hydrogen';
import type {ArticleItemFragment} from 'storefrontapi.generated';
Expand All @@ -26,11 +23,7 @@ export async function loader(args: Route.LoaderArgs) {
* Load data necessary for rendering content above the fold. This is the critical data
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
*/
async function loadCriticalData({
context,
request,
params,
}: Route.LoaderArgs) {
async function loadCriticalData({context, request, params}: Route.LoaderArgs) {
const paginationVariables = getPaginationVariables(request, {
pageBy: 4,
});
Expand Down
5 changes: 1 addition & 4 deletions templates/skeleton/app/routes/blogs._index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
Link,
useLoaderData,
} from 'react-router';
import {Link, useLoaderData} from 'react-router';
import type {Route} from './+types/blogs._index';
import {getPaginationVariables} from '@shopify/hydrogen';
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
Expand Down
6 changes: 1 addition & 5 deletions templates/skeleton/app/routes/cart.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
useLoaderData,
data,
type HeadersFunction,
} from 'react-router';
import {useLoaderData, data, type HeadersFunction} from 'react-router';
import type {Route} from './+types/cart';
import type {CartQueryDataReturn} from '@shopify/hydrogen';
import {CartForm} from '@shopify/hydrogen';
Expand Down
4 changes: 1 addition & 3 deletions templates/skeleton/app/routes/collections.all.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type {Route} from './+types/collections.all';
import {
useLoaderData,
} from 'react-router';
import {useLoaderData} from 'react-router';
import {getPaginationVariables, Image, Money} from '@shopify/hydrogen';
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
import {ProductItem} from '~/components/ProductItem';
Expand Down
10 changes: 2 additions & 8 deletions templates/skeleton/app/routes/pages.$handle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {
useLoaderData,
} from 'react-router';
import {useLoaderData} from 'react-router';
import type {Route} from './+types/pages.$handle';
import {redirectIfHandleIsLocalized} from '~/lib/redirect';

Expand All @@ -22,11 +20,7 @@ export async function loader(args: Route.LoaderArgs) {
* Load data necessary for rendering content above the fold. This is the critical data
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
*/
async function loadCriticalData({
context,
request,
params,
}: Route.LoaderArgs) {
async function loadCriticalData({context, request, params}: Route.LoaderArgs) {
if (!params.handle) {
throw new Error('Missing page handle');
}
Expand Down
5 changes: 1 addition & 4 deletions templates/skeleton/app/routes/policies.$handle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
Link,
useLoaderData,
} from 'react-router';
import {Link, useLoaderData} from 'react-router';
import type {Route} from './+types/policies.$handle';
import {type Shop} from '@shopify/hydrogen/storefront-api-types';

Expand Down
2 changes: 1 addition & 1 deletion templates/skeleton/app/routes/policies._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {PoliciesQuery, PolicyItemFragment} from 'storefrontapi.generated';

export async function loader({context}: Route.LoaderArgs) {
const data: PoliciesQuery = await context.storefront.query(POLICIES_QUERY);

const shopPolicies = data.shop;
const policies: PolicyItemFragment[] = [
shopPolicies?.privacyPolicy,
Expand Down
11 changes: 2 additions & 9 deletions templates/skeleton/app/routes/products.$handle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
redirect,
useLoaderData,
} from 'react-router';
import {redirect, useLoaderData} from 'react-router';
import type {Route} from './+types/products.$handle';
import {
getSelectedProductOptions,
Expand Down Expand Up @@ -40,11 +37,7 @@ export async function loader(args: Route.LoaderArgs) {
* Load data necessary for rendering content above the fold. This is the critical data
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
*/
async function loadCriticalData({
context,
params,
request,
}: Route.LoaderArgs) {
async function loadCriticalData({context, params, request}: Route.LoaderArgs) {
const {handle} = params;
const {storefront} = context;

Expand Down
30 changes: 18 additions & 12 deletions templates/skeleton/app/routes/search.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {
useLoaderData,
} from 'react-router';
import {useLoaderData} from 'react-router';
import type {Route} from './+types/search';
import {getPaginationVariables, Analytics} from '@shopify/hydrogen';
import {SearchForm} from '~/components/SearchForm';
Expand All @@ -10,7 +8,10 @@ import {
type PredictiveSearchReturn,
getEmptyPredictiveSearchResult,
} from '~/lib/search';
import type {RegularSearchQuery, PredictiveSearchQuery} from 'storefrontapi.generated';
import type {
RegularSearchQuery,
PredictiveSearchQuery,
} from 'storefrontapi.generated';

export const meta: Route.MetaFunction = () => {
return [{title: `Hydrogen | Search`}];
Expand Down Expand Up @@ -225,9 +226,13 @@ async function regularSearch({
const term = String(url.searchParams.get('q') || '');

// Search articles, pages, and products for the `q` term
const {errors, ...items}: {errors?: Array<{message: string}>} & RegularSearchQuery = await storefront.query(SEARCH_QUERY, {
variables: {...variables, term},
});
const {
errors,
...items
}: {errors?: Array<{message: string}>} & RegularSearchQuery =
await storefront.query(SEARCH_QUERY, {
variables: {...variables, term},
});

if (!items) {
throw new Error('No search data returned from Shopify API');
Expand Down Expand Up @@ -389,17 +394,18 @@ async function predictiveSearch({
if (!term) return {type, term, result: getEmptyPredictiveSearchResult()};

// Predictively search articles, collections, pages, products, and queries (suggestions)
const {predictiveSearch: items, errors}: PredictiveSearchQuery & {errors?: Array<{message: string}>} = await storefront.query(
PREDICTIVE_SEARCH_QUERY,
{
const {
predictiveSearch: items,
errors,
}: PredictiveSearchQuery & {errors?: Array<{message: string}>} =
await storefront.query(PREDICTIVE_SEARCH_QUERY, {
variables: {
// customize search options as needed
limit,
limitScope: 'EACH',
term,
},
},
);
});

if (errors) {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This integration uses the storefront API (SFAPI) [predictiveSearch](https://shop

| File | Description |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`app/components/SearchFormPredictive.tsx`](../../app/components/SearchFormPredictive.tsx) | A fully customizable form component configured to make form `GET` requests to the `/search` route. |
| [`app/components/SearchFormPredictive.tsx`](../../app/components/SearchFormPredictive.tsx) | A fully customizable form component configured to make form `GET` requests to the `/search` route. |
| [`app/components/SearchResultsPredictive.tsx`](../../app/components/SearchResultsPredictive.tsx) | A fully customizable search results wrapper, that provides compound components to render `articles`, `pages`, `products`, `collections` and `queries`. |

## Instructions
Expand Down Expand Up @@ -217,10 +217,10 @@ export async function loader({request, context}: LoaderFunctionArgs) {
const isPredictive = url.searchParams.has('predictive');

if (!isPredictive) {
return {}
return {};
}

const searchPromise = predictiveSearch({request, context})
const searchPromise = predictiveSearch({request, context});

searchPromise.catch((error: Error) => {
console.error(error);
Expand Down
2 changes: 1 addition & 1 deletion templates/skeleton/guides/search/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export async function loader({request, context}: LoaderFunctionArgs) {
const isRegular = !url.searchParams.has('predictive');

if (!isRegular) {
return {}
return {};
}

const searchPromise = regularSearch({request, context});
Expand Down
2 changes: 1 addition & 1 deletion templates/skeleton/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@shopify/hydrogen-codegen": "workspace:*",
"@shopify/mini-oxygen": "workspace:*",
"@shopify/oxygen-workers-types": "^4.1.6",
"@shopify/prettier-config": "^1.1.2",
"@shopify/prettier-config": "catalog:",
"@total-typescript/ts-reset": "^0.6.1",
"@types/eslint": "^9.6.1",
"@types/react": "catalog:",
Expand Down
Loading