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: 7 additions & 0 deletions .changeset/article-reference-metafield.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@shopify/hydrogen-react': patch
---

Add support for `article_reference` and `list.article_reference` metafield types

These new metafield types were introduced in Storefront API 2025-10, allowing merchants to reference blog articles in metafields.
31 changes: 31 additions & 0 deletions packages/hydrogen-react/src/parse-metafield.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import {getRawMetafield} from './parse-metafield.test.helpers.js';
import {TypeEqual, expectType} from 'ts-expect';
import type {
Article,
Collection,
GenericFile,
MoneyV2,
Expand All @@ -27,6 +28,17 @@ import {type RichTextASTNode} from './RichText.types.js';
*/
describe(`parseMetafield`, () => {
describe(`base metafields`, () => {
it(`article_reference`, () => {
const parsed = parseMetafield<ParsedMetafields['article_reference']>({
type: 'article_reference',
reference: {
__typename: 'Article',
},
});
expect(parsed.parsedValue?.__typename === 'Article').toBe(true);
expectType<null | Article>(parsed?.parsedValue);
});

it(`boolean`, () => {
const meta = getRawMetafield({
type: 'boolean',
Expand Down Expand Up @@ -278,6 +290,25 @@ describe(`parseMetafield`, () => {
});

describe(`list metafields`, () => {
it(`list.article_reference`, () => {
const parsed = parseMetafield<ParsedMetafields['list.article_reference']>(
{
type: 'list.article_reference',
references: {
nodes: [
{__typename: 'Article', id: '0'},
{__typename: 'Article', id: '1'},
],
},
},
);
parsed.parsedValue?.forEach((article, index) => {
expect(article.__typename === 'Article').toBe(true);
expect(index.toString() === article.id).toBe(true);
});
expectType<null | Article[]>(parsed?.parsedValue);
});

it(`list.collection_reference`, () => {
const parsed = parseMetafield<
ParsedMetafields['list.collection_reference']
Expand Down
19 changes: 19 additions & 0 deletions packages/hydrogen-react/src/parse-metafield.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
Article,
Collection,
CurrencyCode,
GenericFile,
Expand Down Expand Up @@ -44,6 +45,7 @@ export function parseMetafield<ReturnGeneric>(
parsedValue: metafield.value === 'true',
} as ReturnGeneric;

case 'article_reference':
case 'collection_reference':
case 'file_reference':
case 'page_reference':
Expand Down Expand Up @@ -156,6 +158,7 @@ export function parseMetafield<ReturnGeneric>(
parsedValue: Number(metafield.value),
} as ReturnGeneric;

case 'list.article_reference':
case 'list.collection_reference':
case 'list.file_reference':
case 'list.page_reference':
Expand Down Expand Up @@ -197,6 +200,7 @@ export function parseJSON(json: string): unknown {

// taken from https://shopify.dev/apps/metafields/types
export const allMetafieldTypesArray = [
'article_reference',
'boolean',
'collection_reference',
'color',
Expand All @@ -219,6 +223,7 @@ export const allMetafieldTypesArray = [
'volume',
'weight',
// list metafields
'list.article_reference',
'list.collection_reference',
'list.color',
'list.date',
Expand Down Expand Up @@ -250,6 +255,8 @@ export type MetafieldTypeTypes = (typeof allMetafieldTypesArray)[number];
* `parsedMetafield.parsedValue`'s type is now `boolean`
*/
export type ParsedMetafields<ExtraTypeGeneric = void> = {
/** A Metafield that's been parsed, with a `parsedValue` of an `Article` object (as defined by the Storefront API) */
article_reference: Simplify<ArticleParsedRefMetafield>;
/** A Metafield that's been parsed, with a `parsedValue` of `boolean` */
boolean: Simplify<BooleanParsedMetafield>;
/** A Metafield that's been parsed, with a `parsedValue` of a `Collection` object (as defined by the Storefront API) */
Expand Down Expand Up @@ -299,6 +306,8 @@ export type ParsedMetafields<ExtraTypeGeneric = void> = {
/** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */
weight: Simplify<MeasurementParsedMetafield>;
// list metafields
/** A Metafield that's been parsed, with a `parsedValue` of an array of `Article` objects (as defined by the Storefront API) */
'list.article_reference': Simplify<ArticleListParsedRefMetafield>;
/** A Metafield that's been parsed, with a `parsedValue` of an array of `Collection` objects (as defined by the Storefront API) */
'list.collection_reference': Simplify<CollectionListParsedRefMetafield>;
/** A Metafield that's been parsed, with a `parsedValue` of an array of strings */
Expand Down Expand Up @@ -385,6 +394,11 @@ type NumberParsedMetafield = MetafieldBaseType & {
parsedValue: number | null;
};

type ArticleParsedRefMetafield = MetafieldBaseType & {
type: 'article_reference';
parsedValue: Article | null;
};

type PageParsedRefMetafield = MetafieldBaseType & {
type: 'page_reference';
parsedValue: Page | null;
Expand All @@ -410,6 +424,11 @@ type VariantParsedRefMetafield = MetafieldBaseType & {
parsedValue: ProductVariant | null;
};

type ArticleListParsedRefMetafield = MetafieldBaseType & {
type: 'list.article_reference';
parsedValue: Array<Article> | null;
};

type CollectionListParsedRefMetafield = MetafieldBaseType & {
type: 'list.collection_reference';
parsedValue: Array<Collection> | null;
Expand Down
Loading