0

Create Product

by
Published Nov 8, 2023

Create a product, optionally with options, variants and images.

Script shopify Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 2 hours ago
1
//native
2

3
/**
4
 * Create Product
5
 * Create a product, optionally with options (e.g. Size: S, M, L) and one variant per option combination. Each variant lists its option values in the same order as options. Without options, Shopify creates a single default variant. Image URLs are fetched by Shopify and attached as media.
6
 */
7
export async function main(
8
  auth: RT.Shopify,
9
  title: string,
10
  description_html: string | undefined,
11
  vendor: string | undefined,
12
  product_type: string | undefined,
13
  tags: string[] | undefined,
14
  status: "DRAFT" | "ACTIVE" | "UNLISTED" | "ARCHIVED" | undefined,
15
  options: { name: string; values: string[] }[] | undefined,
16
  variants:
17
    | {
18
        option_values: string[]
19
        price?: string
20
        compare_at_price?: string
21
        sku?: string
22
      }[]
23
    | undefined,
24
  image_urls: string[] | undefined
25
) {
26
  const response = await fetch(
27
    `https://${auth.store_name}.myshopify.com/admin/api/2026-10/graphql.json`,
28
    {
29
      method: "POST",
30
      headers: {
31
        "X-Shopify-Access-Token": auth.token,
32
        "Content-Type": "application/json",
33
        Accept: "application/json",
34
      },
35
      body: JSON.stringify({
36
        query: `mutation ($input: ProductSetInput!) { productSet(input: $input, synchronous: true) { product { id legacyResourceId title handle status vendor productType tags createdAt options { id name optionValues { id name } } variants(first: 100) { nodes { id legacyResourceId title sku price compareAtPrice selectedOptions { name value } inventoryItem { id } } } } userErrors { field message code } } }`,
37
        variables: {
38
          input: {
39
            title,
40
            descriptionHtml: description_html || undefined,
41
            vendor: vendor || undefined,
42
            productType: product_type || undefined,
43
            tags: tags?.length ? tags : undefined,
44
            status: status || undefined,
45
            productOptions: options?.length
46
              ? options.map((o) => ({
47
                  name: o.name,
48
                  values: o.values.map((name) => ({ name })),
49
                }))
50
              : undefined,
51
            variants: variants?.length
52
              ? variants.map((v) => ({
53
                  optionValues: v.option_values.map((name, i) => ({
54
                    optionName: options?.[i]?.name,
55
                    name,
56
                  })),
57
                  price: v.price || undefined,
58
                  compareAtPrice: v.compare_at_price || undefined,
59
                  sku: v.sku || undefined,
60
                }))
61
              : undefined,
62
            files: image_urls?.length
63
              ? image_urls.map((originalSource) => ({
64
                  originalSource,
65
                  contentType: "IMAGE",
66
                }))
67
              : undefined,
68
          },
69
        },
70
      }),
71
    }
72
  )
73

74
  if (!response.ok) {
75
    throw new Error(`${response.status} ${await response.text()}`)
76
  }
77

78
  const { data, errors } = await response.json()
79
  if (errors) {
80
    throw new Error(JSON.stringify(errors))
81
  }
82
  if (data.productSet.userErrors.length) {
83
    throw new Error(JSON.stringify(data.productSet.userErrors))
84
  }
85

86
  return data.productSet
87
}
88

Other submissions
  • Submitted by hugo697 Typescript (fetch-only)
    Created 528 days ago
    1
    type Shopify = {
    2
      token: string;
    3
      store_name: string;
    4
    };
    5
    /**
    6
     * Creates a new product
    7
     * Creates a new product. If you want to set the product's SEO information, then you can use the following properties:  metafields_global_title_tag: The name of the product used for SEO purposes. Generally added to the <meta name='title'> tag. metafields_global_description_tag: A description of the product used for SEO purposes. Generally added to the <meta name='description'> tag.
    8
     */
    9
    export async function main(
    10
      auth: Shopify,
    11
      api_version: string = "2023-10",
    12
      body: {
    13
        product?: {
    14
          body_html?: string;
    15
          product_type?: string;
    16
          published?: boolean;
    17
          title?: string;
    18
          vendor?: string;
    19
          [k: string]: unknown;
    20
        };
    21
        [k: string]: unknown;
    22
      }
    23
    ) {
    24
      const url = new URL(
    25
        `https://${auth.store_name}.myshopify.com/admin/api/${api_version}/products.json`
    26
      );
    27
    
    
    28
      const response = await fetch(url, {
    29
        method: "POST",
    30
        headers: {
    31
          "Content-Type": "application/json",
    32
          "X-Shopify-Access-Token": auth.token,
    33
        },
    34
        body: JSON.stringify(body),
    35
      });
    36
      if (!response.ok) {
    37
        const text = await response.text();
    38
        throw new Error(`${response.status} ${text}`);
    39
      }
    40
      return await response.json();
    41
    }
    42