Skip to content
Draft
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
26 changes: 21 additions & 5 deletions packages/hydrogen-react/docs/build-docs.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
COMPILE_DOCS="pnpm exec tsc --project docs/tsconfig.docs.json --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --overridePath ./docs/typeOverride.json --input ./src --output ./docs/generated && rm -rf src/**/*.doc.js src/*.doc.js"
COMPILE_STATIC_PAGES="pnpm exec tsc docs/staticPages/*.doc.ts --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --isLandingPage --input ./docs/staticPages --output ./docs/generated && rm -rf docs/staticPages/*.doc.js"
OUTPUT_DIR="./docs/generated"
V2_TEMP_DIR="./docs/generated_v2_temp"

COMPILE_DOCS_V2="generate-docs --overridePath ./docs/typeOverride.json --input ./src --output $V2_TEMP_DIR"
COMPILE_DOCS="pnpm exec tsc --project docs/tsconfig.docs.json --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --overridePath ./docs/typeOverride.json --input ./src --output $OUTPUT_DIR && rm -rf src/**/*.doc.js src/*.doc.js"
COMPILE_STATIC_PAGES="pnpm exec tsc docs/staticPages/*.doc.ts --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --isLandingPage --input ./docs/staticPages --output $OUTPUT_DIR && rm -rf docs/staticPages/*.doc.js"

if [ "$1" = "isTest" ];
then
COMPILE_DOCS="pnpm exec tsc --project docs/tsconfig.docs.json --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --overridePath ./docs/typeOverride.json --input ./src --output ./docs/temp && rm -rf src/**/*.doc.js src/*.doc.js"
COMPILE_STATIC_PAGES="pnpm exec tsc docs/staticPages/*.doc.ts --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --isLandingPage --input ./docs/staticPages --output ./docs/temp && rm -rf docs/staticPages/*.doc.js"
OUTPUT_DIR="./docs/temp"
V2_TEMP_DIR="./docs/temp_v2"
COMPILE_DOCS_V2="generate-docs --overridePath ./docs/typeOverride.json --input ./src --output $V2_TEMP_DIR"
COMPILE_DOCS="pnpm exec tsc --project docs/tsconfig.docs.json --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --overridePath ./docs/typeOverride.json --input ./src --output $OUTPUT_DIR && rm -rf src/**/*.doc.js src/*.doc.js"
COMPILE_STATIC_PAGES="pnpm exec tsc docs/staticPages/*.doc.ts --types react --moduleResolution node --target esNext --module CommonJS && generate-docs --isLandingPage --input ./docs/staticPages --output $OUTPUT_DIR && rm -rf docs/staticPages/*.doc.js"
fi

eval $COMPILE_DOCS
eval $COMPILE_DOCS_V2
eval $COMPILE_DOCS
eval $COMPILE_STATIC_PAGES

cp "$V2_TEMP_DIR/generated_docs_data_v2.json" "$OUTPUT_DIR/generated_docs_data_v2.json"
rm -rf "$V2_TEMP_DIR"

if [ "$1" != "isTest" ];
then
node ./docs/copy-docs-to-shopify-dev.mjs
fi
59 changes: 59 additions & 0 deletions packages/hydrogen-react/docs/copy-docs-to-shopify-dev.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {promises as fs} from 'fs';
import path from 'path';
import {fileURLToPath} from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const SHOPIFY_DEV_DB_SUBPATH =
'areas/platforms/shopify-dev/db/data/docs/templated_apis';

const HYDROGEN_REACT_VERSION = '2026-04';

async function copyGeneratedToShopifyDev() {
const generatedDocsPath = path.resolve(
__dirname,
'./generated/generated_docs_data_v2.json',
);

// Find the shopify-dev repo: try world first, then relative fallback
const rootPath = path.resolve(__dirname, '../../..');
const worldPath = path.join(process.env.HOME, 'world/trees/root/src');

let shopifyDevPath;
try {
await fs.access(worldPath);
shopifyDevPath = worldPath;
} catch {
shopifyDevPath = path.join(rootPath, '../../../shopify-dev');
}

const shopifyDevDBPath = path.join(shopifyDevPath, SHOPIFY_DEV_DB_SUBPATH);

try {
await fs.access(shopifyDevDBPath);
} catch {
console.warn(
`[h2-react:docs] shopify-dev not found at ${shopifyDevDBPath}. Skipping copy.`,
);
return;
}

const destDir = path.join(
shopifyDevDBPath,
'hydrogen_react',
HYDROGEN_REACT_VERSION,
);
const destFile = path.join(destDir, 'generated_docs_data_v2.json');

await fs.mkdir(destDir, {recursive: true});
await fs.copyFile(generatedDocsPath, destFile);

console.log(
`[h2-react:docs] Copied generated_docs_data_v2.json → ${destFile}`,
);
}

copyGeneratedToShopifyDev().catch((err) => {
console.error(err);
process.exit(1);
});
292 changes: 198 additions & 94 deletions packages/hydrogen-react/docs/generated/generated_docs_data.json

Large diffs are not rendered by default.

7,436 changes: 7,436 additions & 0 deletions packages/hydrogen-react/docs/generated/generated_docs_data_v2.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"type": "Generic",
"anchorLink": "authentication",
"title": "Authentication",
"sectionContent": "To use Hydrogen React, you need to authenticate with and make requests to the [Storefront API](/docs/api/storefront). Hydrogen React includes an [API client](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient) to securely handle API queries and mutations.\n\nYou can create and manage Storefront API access tokens by installing the [Headless sales channel](https://apps.shopify.com/headless) on your store.\n\nApps have access to [two kinds of tokens](/docs/api/usage/authentication#access-tokens-for-the-storefront-api): a public API token, which can be used in client-side code, and a private API token, which should only be used in server-side contexts and never exposed publicly.",
"sectionContent": "To use Hydrogen React, you need to authenticate with and make requests to the [Storefront API](/docs/api/storefront). Hydrogen React includes an [API client](/docs/api/hydrogen-react/2026-04/utilities/createstorefrontclient) to securely handle API queries and mutations.\n\nYou can create and manage Storefront API access tokens by installing the [Headless sales channel](https://apps.shopify.com/headless) on your store.\n\nApps have access to [two kinds of tokens](/docs/api/usage/authentication#access-tokens-for-the-storefront-api): a public API token, which can be used in client-side code, and a private API token, which should only be used in server-side contexts and never exposed publicly.",
"sectionCard": [
{
"subtitle": "Install",
Expand Down
2 changes: 1 addition & 1 deletion packages/hydrogen-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
"@graphql-codegen/introspection": "^4.0.3",
"@graphql-codegen/typescript": "^4.1.3",
"@ladle/react": "^5.0.1",
"@shopify/generate-docs": "0.16.4",
"@shopify/generate-docs": "1.1.2",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.6.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/AddToCartButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type AddToCartButtonProps<AsType extends React.ElementType = 'button'> =
/**
* The `AddToCartButton` component renders a button that adds an item to the cart when pressed.
* It must be a descendent of the `CartProvider` component.
* @publicDocs
*/
export function AddToCartButton<AsType extends React.ElementType = 'button'>(
props: AddToCartButtonProps<AsType>,
Expand Down Expand Up @@ -113,6 +114,7 @@ export function AddToCartButton<AsType extends React.ElementType = 'button'>(
}

// This is only for documentation purposes, and it is not used in the code.
/** @publicDocs */
export interface AddToCartButtonPropsForDocs<
AsType extends React.ElementType = 'button',
>
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/BuyNowButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type BuyNowButtonProps<AsType extends React.ElementType = 'button'> =
/**
* The `BuyNowButton` component renders a button that adds an item to the cart and redirects the customer to checkout.
* Must be a child of a `CartProvider` component.
* @publicDocs
*/
export function BuyNowButton<AsType extends React.ElementType = 'button'>(
props: BuyNowButtonProps<AsType>,
Expand Down Expand Up @@ -77,6 +78,7 @@ export function BuyNowButton<AsType extends React.ElementType = 'button'>(
}

// This is only for documentation purposes, and it is not used in the code.
/** @publicDocs */
export interface BuyNowButtonPropsForDocs<
AsType extends React.ElementType = 'button',
>
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/CartCheckoutButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type CartCheckoutButtonProps = Omit<BaseButtonProps<'button'>, 'onClick'> &
/**
* The `CartCheckoutButton` component renders a button that redirects to the checkout URL for the cart.
* It must be a descendent of a `CartProvider` component.
* @publicDocs
*/
export function CartCheckoutButton(
props: CartCheckoutButtonProps,
Expand Down Expand Up @@ -44,6 +45,7 @@ export function CartCheckoutButton(
// This is only for documentation purposes, and it is not used in the code.
// we ignore this issue because it makes the documentation look better than the equivalent `type` that it wants us to convert to
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
/** @publicDocs */
export interface CartCheckoutButtonPropsForDocs<
AsType extends React.ElementType = 'button',
> extends Omit<CustomBaseButtonProps<AsType>, 'onClick'> {}
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/CartCost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type CartCostProps = Omit<React.ComponentProps<typeof Money>, 'data'> &
* The `CartCost` component renders a `Money` component with the cost associated with the `amountType` prop.
* If no `amountType` prop is specified, then it defaults to `totalAmount`.
* Depends on `useCart()` and must be a child of `<CartProvider/>`
* @publicDocs
*/
export function CartCost(props: CartCostProps): JSX.Element | null {
const {cost} = useCart();
Expand Down Expand Up @@ -43,5 +44,6 @@ export function CartCost(props: CartCostProps): JSX.Element | null {
}

// This is only for documentation purposes, and it is not used in the code.
/** @publicDocs */
export interface CartCostPropsForDocs<AsType extends React.ElementType = 'div'>
extends Omit<MoneyPropsBase<AsType>, 'data'>, CartCostPropsBase {}
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/CartLineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const CartLineContext = createContext<CartLinePartialDeep | null>(null);

/**
* The `useCartLine` hook provides access to the [CartLine object](https://shopify.dev/api/storefront/2026-04/objects/cartline) from the Storefront API. It must be a descendent of a `CartProvider` component.
* @publicDocs
*/
export function useCartLine(): CartLinePartialDeep {
const context = useContext(CartLineContext);
Expand All @@ -34,6 +35,7 @@ type CartLineProviderProps = {

/**
* The `CartLineProvider` component creates a context for using a cart line.
* @publicDocs
*/
export function CartLineProvider({
children,
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/CartLineQuantity.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {ComponentPropsWithoutRef, ElementType} from 'react';
import {useCartLine} from './CartLineProvider.js';

/** @publicDocs */
interface CartLineQuantityBaseProps<
ComponentGeneric extends ElementType = 'span',
> {
Expand All @@ -19,6 +20,7 @@ export type CartLineQuantityProps<ComponentGeneric extends ElementType> =
* The `<CartLineQuantity/>` component renders a `span` (or another element / component that can be customized by the `as` prop) with the cart line's quantity.
*
* It must be a descendent of a `<CartLineProvider/>` component, and uses the `useCartLine()` hook internally.
* @publicDocs
*/
export function CartLineQuantity<ComponentGeneric extends ElementType = 'span'>(
props: CartLineQuantityProps<ComponentGeneric>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type CartLineQuantityAdjustButtonProps<
* The `<CartLineQuantityAdjustButton />` component renders a button that adjusts the cart line's quantity when pressed.
*
* It must be a descendent of `<CartLineProvider/>` and `<CartProvider/>`.
* @publicDocs
*/
export function CartLineQuantityAdjustButton<
AsType extends React.ElementType = 'button',
Expand Down
7 changes: 6 additions & 1 deletion packages/hydrogen-react/src/CartProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ import {useShop} from './ShopifyProvider.js';
export const CartContext = createContext<CartWithActions | null>(null);

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type UseCartDocs = () => CartWithActionsDocs;
/**
* `useCart` hook must be a descendent of a `CartProvider` component.
* @publicDocs */
export type UseCartDocs = () => CartWithActionsDocs;

/**
* The `useCart` hook provides access to the cart object. It must be a descendent of a `CartProvider` component.
* @publicDocs
*/
export function useCart(): CartWithActions {
const context = useContext(CartContext);
Expand Down Expand Up @@ -109,6 +113,7 @@ type CartProviderProps = {
* There are also props that trigger when a call to the Storefront API is completed, such as `onLineAddComplete={}` when the fetch request for adding a line to the cart completes.
*
* The `CartProvider` component must be a descendant of the `ShopifyProvider` component.
* @publicDocs
*/
export function CartProvider({
children,
Expand Down
4 changes: 4 additions & 0 deletions packages/hydrogen-react/src/ExternalVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import type {ExternalVideo as ExternalVideoType} from './storefront-api-types.js
import type {Entries, PartialDeep} from 'type-fest';
import {forwardRef, IframeHTMLAttributes} from 'react';

/**
* Takes in the same props as a native `<iframe>` element, except for `src`.
* @publicDocs */
export interface ExternalVideoBaseProps {
/**
* An object with fields that correspond to the Storefront API's [ExternalVideo object](https://shopify.dev/api/storefront/reference/products/externalvideo).
Expand All @@ -23,6 +26,7 @@ export type ExternalVideoProps = Omit<
/**
* The `ExternalVideo` component renders an embedded video for the Storefront
* API's [ExternalVideo object](https://shopify.dev/api/storefront/reference/products/externalvideo).
* @publicDocs
*/
export const ExternalVideo = forwardRef<HTMLIFrameElement, ExternalVideoProps>(
(props, ref): JSX.Element => {
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export type Loader = (params: LoaderParams) => string;
*/
type Crop = 'center' | 'top' | 'bottom' | 'left' | 'right';

/** @publicDocs */
export type HydrogenImageProps = React.ComponentPropsWithRef<'img'> &
HydrogenImageBaseProps;

Expand Down Expand Up @@ -148,6 +149,7 @@ export const IMAGE_FRAGMENT = `#graphql
* ```
*
* {@link https://shopify.dev/docs/api/hydrogen-react/components/image}
* @publicDocs
*/
export const Image = React.forwardRef<HTMLImageElement, HydrogenImageProps>(
(
Expand Down
4 changes: 4 additions & 0 deletions packages/hydrogen-react/src/MediaFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js'
type BaseProps = React.HTMLAttributes<
HTMLImageElement | HTMLVideoElement | HTMLIFrameElement | ModelViewerElement
>;
/**
* MediaFile renders an `Image`, `Video`, `ExternalVideo`, or `ModelViewer` component. Use the `mediaOptions` prop to customize the props sent to each of these components.
* @publicDocs */
export interface MediaFileProps extends BaseProps {
/** An object with fields that correspond to the Storefront API's [Media object](https://shopify.dev/api/storefront/reference/products/media). */
data: PartialDeep<MediaEdgeType['node'], {recurseIntoArrays: true}>;
Expand All @@ -34,6 +37,7 @@ type MediaOptions = {
* The `MediaFile` component renders the media for the Storefront API's
* [Media object](https://shopify.dev/api/storefront/reference/products/media). It renders an `Image`, a
* `Video`, an `ExternalVideo`, or a `ModelViewer` depending on the `__typename` of the `data` prop.
* @publicDocs
*/
export function MediaFile({
data,
Expand Down
1 change: 1 addition & 0 deletions packages/hydrogen-react/src/ModelViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type ModelViewerBaseProps = {
* The `model-viewer` custom element is lazily downloaded through a dynamically-injected `<script type="module">` tag when the `<ModelViewer />` component is rendered
*
* ModelViewer is using version `1.21.1` of the `@google/model-viewer` library.
* @publicDocs
*/
export function ModelViewer(props: ModelViewerProps): JSX.Element | null {
const [modelViewer, setModelViewer] = useState<undefined | HTMLElement>(
Expand Down
1 change: 1 addition & 0 deletions packages/hydrogen-react/src/Money.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type MoneyProps<ComponentGeneric extends React.ElementType> =
* measurementSeparator=" per "
* />
* ```
* @publicDocs
*/
export function Money<ComponentGeneric extends React.ElementType = 'div'>({
data,
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/ProductPrice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface ProductPriceProps {
/**
* The `ProductPrice` component renders a `Money` component with the product
* [`priceRange`](https://shopify.dev/api/storefront/reference/products/productpricerange)'s `maxVariantPrice` or `minVariantPrice`, for either the regular price or compare at price range.
* @publicDocs
*/
export function ProductPrice<
ComponentGeneric extends React.ElementType = 'div',
Expand Down Expand Up @@ -101,6 +102,7 @@ export function ProductPrice<
}

// This is only for documentation purposes, and it is not used in the code.
/** @publicDocs */
export interface ProductPricePropsForDocs<
AsType extends React.ElementType = 'div',
>
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/ProductProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface ProductProviderProps {
* `<ProductProvider />` is a context provider that enables use of the `useProduct()` hook.
*
* It helps manage selected options and variants for a product.
* @publicDocs
*/
export function ProductProvider({
children,
Expand Down Expand Up @@ -206,6 +207,7 @@ export function ProductProvider({

/**
* Provides access to the context value provided by `<ProductProvider />`. Must be a descendent of `<ProductProvider />`.
* @publicDocs
*/
export function useProduct(): ProductHookValue {
const context = useContext(ProductOptionsContext);
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/RichText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface RichTextPropsBase<ComponentGeneric extends React.ElementType> {
plain?: boolean;
}

/** @publicDocs */
export function RichText<ComponentGeneric extends React.ElementType = 'div'>({
as,
data,
Expand Down Expand Up @@ -209,5 +210,6 @@ function richTextToString(
}

// This is only for documentation purposes, and it is not used in the code.
/** @publicDocs */
export type RichTextPropsForDocs<AsType extends React.ElementType = 'div'> =
RichTextPropsBase<AsType>;
1 change: 1 addition & 0 deletions packages/hydrogen-react/src/ShopPayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function isChannel(
* The `ShopPayButton` component renders a button that redirects to the Shop Pay checkout.
* It renders a [`<shop-pay-button>`](https://shopify.dev/custom-storefronts/tools/web-components) custom element, for which it will lazy-load the source code automatically.
* It relies on the `<ShopProvider>` context provider.
* @publicDocs
*/
export function ShopPayButton({
channel,
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/ShopifyProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function isSfapiProxyEnabled() {

/**
* The `<ShopifyProvider/>` component enables use of the `useShop()` hook. The component should wrap your app.
* @publicDocs
*/
export function ShopifyProvider({
children,
Expand Down Expand Up @@ -118,6 +119,7 @@ export function ShopifyProvider({

/**
* Provides access to the `shopifyConfig` prop of `<ShopifyProvider/>`. Must be a descendent of `<ShopifyProvider/>`.
* @publicDocs
*/
export function useShop(): ShopifyContextValue {
const shopContext = useContext(ShopifyContext);
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrogen-react/src/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {shopifyLoader} from './Image.js';
import type {Video as VideoType} from './storefront-api-types.js';
import type {PartialDeep} from 'type-fest';

/** @publicDocs */
export interface VideoProps {
/** An object with fields that correspond to the Storefront API's [Video object](https://shopify.dev/api/storefront/2026-04/objects/video). */
data: PartialDeep<VideoType, {recurseIntoArrays: true}>;
Expand All @@ -16,6 +17,7 @@ export interface VideoProps {

/**
* The `Video` component renders a `video` for the Storefront API's [Video object](https://shopify.dev/api/storefront/reference/products/video).
* @publicDocs
*/
export const Video = forwardRef<
HTMLVideoElement,
Expand Down
Loading
Loading