--- title: Collections description: >- Collection pages display information about product groupings, including the products within each collection, collection rules, and display settings. Extensions on these pages help merchants organize inventory and streamline collection management workflows. api_version: 2026-01 api_name: admin-extensions source_url: html: 'https://shopify.dev/docs/api/admin-extensions/latest/targets/collections' md: 'https://shopify.dev/docs/api/admin-extensions/latest/targets/collections.md' --- # Collections Collection pages display information about product groupings, including the products within each collection, collection rules, and display settings. Extensions on these pages help merchants organize inventory and streamline collection management workflows. ### Use cases * **Bulk product tagging:** Automatically apply tags or metafields to all products within a collection based on custom rules or external data sources. * **Collection sync:** Synchronize collection data with external platforms like marketplaces, PIM systems, or marketing tools. * **SEO optimization:** Generate and apply SEO metadata, descriptions, or structured data for collections to improve search visibility. * **Inventory alerts:** Check stock levels across collection products and notify merchants of low inventory or out-of-stock items. * **Collection analytics:** Display performance metrics or generate reports for products within a collection from external analytics platforms. ![Collections targets overview](https://shopify.dev/assets/assets/images/templated-apis-screenshots/admin-extensions/targets-overview-images/admin.collection.overview-BEVB9y8S.png) *** ## Collection details targets Use [action and block targets](https://shopify.dev/docs/api/admin-extensions/2026-01#building-your-extension) to extend the collection details page. Add workflows and contextual information that help merchants manage collection relationships and access integrated collection data. Action targets open as modal overlays from the **More actions** menu, while block targets display as inline cards. The examples demonstrate fetching data from Shopify's [direct API](https://shopify.dev/docs/api/admin-extensions/2026-01#direct-api-access) or your [app's backend](https://shopify.dev/docs/api/admin-extensions/2026-01#app-authentication). ### Collection details action target `admin.collection-details.action.render` Renders an admin action extension on the collection details page. Merchants can access this extension from the **More actions** menu. Use this target to provide workflows that operate on collection data, such as syncing with external systems, exporting collection information, or managing credit terms. Extensions at this target can access collection data through the `data` property in the [Action Extension API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/core-apis/action-extension-api). The action renders in a modal overlay, providing space for multi-step workflows, forms, and confirmations. ### Support Components (55) APIs (1) ### Supported components * [Admin action](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/settings-and-templates/admin-action) * [Avatar](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/avatar) * [Badge](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/badge) * [Banner](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/banner) * [Box](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/box) * [Button](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/button) * [Button group](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/button-group) * [Checkbox](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/checkbox) * [Chip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/chip) * Choice * [Choice list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/choice-list) * [Clickable](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/clickable) * [Clickable chip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/clickable-chip) * [Color field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/color-field) * [Color picker](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/color-picker) * [Date field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/date-field) * [Date picker](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/date-picker) * [Divider](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/divider) * [Drop zone](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/drop-zone) * [Email field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/email-field) * [Grid](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/grid) * Grid item * [Heading](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/heading) * [Icon](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/icon) * [Image](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/image) * [Link](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/link) * List item * [Menu](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/menu) * [Money field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/money-field) * [Number field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/number-field) * Option * Option group * [Ordered list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/ordered-list) * [Paragraph](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/paragraph) * [Password field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/password-field) * [Query container](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/query-container) * [Search field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/search-field) * [Section](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/section) * [Select](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/select) * [Spinner](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/spinner) * [Stack](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/stack) * [Switch](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/switch) * [Table](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/table) * Table body * Table cell * Table header * Table header row * Table row * [Text](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/text) * [Text area](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/text-area) * [Text field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/text-field) * [Thumbnail](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/thumbnail) * [Tooltip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/tooltip) * [Url field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/url-field) * [Unordered list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/unordered-list) ### Available APIs * [Action Extension API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/core-apis/action-extension-api) Examples ### Examples * #### ##### Description Add an action extension that exports all products in a collection to a CSV file. This example demonstrates calling your app backend to generate and download a product export. ##### jsx ```jsx import {render} from 'preact'; import {useState} from 'preact/hooks'; export default async () => { render(, document.body); }; const Extension = () => { const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const [error, setError] = useState(false); const [includeVariants, setIncludeVariants] = useState(true); const [includePricing, setIncludePricing] = useState(true); const [includeInventory, setIncludeInventory] = useState(false); const handleExport = async () => { setLoading(true); setError(false); const collectionId = shopify.data.selected[0].id; try { const response = await fetch('https://your-app.com/api/collections/export', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ collectionId, options: { includeVariants, includePricing, includeInventory, }, }), }); if (response.ok) { const blob = await response.blob(); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'collection-products.csv'; link.click(); URL.revokeObjectURL(url); setSuccess(true); shopify.close(); } else { setError(true); } } catch (err) { setError(true); } finally { setLoading(false); } }; return ( {success && ( Export complete! Your download should start automatically. )} {error && ( Failed to export products. Please try again. )} setIncludeVariants(e.currentTarget.checked)} /> setIncludePricing(e.currentTarget.checked)} /> setIncludeInventory(e.currentTarget.checked)} /> {loading ? 'Exporting...' : 'Export to CSV'} shopify.close()}> Cancel ); }; ``` * #### ##### Description Add an action extension that pushes collection data to an external content management system. This example demonstrates fetching collection details using \[GraphQL Admin API]\(/docs/api/admin-graphql) and syncing to a CMS platform. ##### jsx ```jsx import {render} from 'preact'; import {useState} from 'preact/hooks'; export default async () => { render(, document.body); }; const Extension = () => { const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const [error, setError] = useState(null); const [includeProducts, setIncludeProducts] = useState(true); const [includeImages, setIncludeImages] = useState(true); const handleSync = async () => { setLoading(true); setError(null); const collectionId = shopify.data.selected[0].id; try { const response = await fetch('shopify:admin/api/graphql.json', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ query: `query GetCollection($id: ID!) { collection(id: $id) { id title description handle image { url altText } productsCount { count } seo { title description } } }`, variables: {id: collectionId}, }), }); const {data} = await response.json(); if (data?.collection) { // Simulate CMS sync await new Promise((resolve) => setTimeout(resolve, 800)); setSuccess(true); shopify.close(); } else { setError('Collection not found'); } } catch (err) { setError('Failed to sync collection to CMS'); } finally { setLoading(false); } }; return ( {success && ( Collection synced to CMS successfully! )} {error && ( {error} )} setIncludeProducts(e.currentTarget.checked)} /> setIncludeImages(e.currentTarget.checked)} /> Collection data will be pushed to your connected CMS. {loading ? 'Syncing...' : 'Sync to CMS'} shopify.close()}> Cancel ); }; ``` ### Collection details action (should render) target `admin.collection-details.action.should-render` Controls the render state of an admin action extension on the collection details page. Use this target to conditionally show or hide your action extension based on the collection's properties, such as status, configuration, or specific business requirements. This target returns a boolean value that determines whether the corresponding action extension appears in the **More actions** menu. The extension evaluates each time the page loads. ### Support Components (0) APIs (1) ### Supported components \- ### Available APIs * [Should Render API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/utility-apis/should-render-api) Examples ### Examples * #### ##### Description Show the collection performance action only when the collection is enrolled in your app's analytics tracking system. ##### jsx ```jsx export default async () => { const collectionId = shopify.data.selected[0].id; try { const response = await fetch('https://your-app.com/api/collections/check-tracking', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ collectionId, checkType: 'performance-tracking', }), }); if (!response.ok) { console.error('API error:', response.status); return { display: false }; } const result = await response.json(); // Show action if collection is being tracked and has metrics data return { display: result.isTracked && result.hasMetricsData, }; } catch (err) { console.error('Failed to check collection tracking status:', err); return { display: false }; } }; ``` * #### ##### Description Add an action extension that only appears on collection details when the collection contains products that are out of stock, using the \[GraphQL Admin API]\(/docs/api/admin-graphql) to check inventory status. ##### jsx ```jsx export default async () => { const collectionId = shopify.data.selected[0].id; try { const response = await fetch('shopify:admin/api/graphql.json', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: `query GetCollectionProducts($id: ID!) { collection(id: $id) { products(first: 50) { nodes { totalInventory status } } } }`, variables: { id: collectionId }, }), }); const { data } = await response.json(); const products = data?.collection?.products?.nodes || []; // Check if any active products have zero inventory const hasOutOfStock = products.some( (product) => product.status === 'ACTIVE' && product.totalInventory === 0 ); return { display: hasOutOfStock }; } catch (err) { console.error('Error checking collection inventory:', err); return { display: false }; } }; ``` ### Collection details block target `admin.collection-details.block.render` Renders an admin block extension inline on the collection details page. Use this target to display contextual information, analytics, or status updates related to the collection without requiring merchant interaction to open a modal. Extensions at this target can access collection data through the `data` property in the [Block Extension API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/core-apis/block-extension-api). Blocks appear as cards on the page and can show real-time data, insights, or quick actions, providing persistent visibility for information merchants need to see at a glance. ### Support Components (56) APIs (1) ### Supported components * [Admin block](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/settings-and-templates/admin-block) * [Avatar](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/avatar) * [Badge](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/badge) * [Banner](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/banner) * [Box](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/box) * [Button](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/button) * [Button group](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/button-group) * [Checkbox](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/checkbox) * [Chip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/chip) * Choice * [Choice list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/choice-list) * [Clickable](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/clickable) * [Clickable chip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/clickable-chip) * [Color field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/color-field) * [Color picker](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/color-picker) * [Date field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/date-field) * [Date picker](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/date-picker) * [Divider](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/divider) * [Drop zone](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/drop-zone) * [Email field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/email-field) * [Form](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/form) * [Grid](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/grid) * Grid item * [Heading](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/heading) * [Icon](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/icon) * [Image](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/image) * [Link](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/link) * List item * [Menu](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/menu) * [Money field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/money-field) * [Number field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/number-field) * Option * Option group * [Ordered list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/ordered-list) * [Paragraph](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/paragraph) * [Password field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/password-field) * [Query container](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/query-container) * [Search field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/search-field) * [Section](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/section) * [Select](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/select) * [Spinner](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/spinner) * [Stack](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/stack) * [Switch](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/switch) * [Table](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/table) * Table body * Table cell * Table header * Table header row * Table row * [Text](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/text) * [Text area](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/text-area) * [Text field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/text-field) * [Thumbnail](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/thumbnail) * [Tooltip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/tooltip) * [Url field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/url-field) * [Unordered list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/unordered-list) ### Available APIs * [Block Extension API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/core-apis/block-extension-api) Examples ### Examples * #### ##### Description Create a block extension that displays sales and traffic metrics for a collection by fetching analytics data from your app backend. ##### jsx ```jsx import {render} from 'preact'; import {useState, useEffect} from 'preact/hooks'; export default async () => { render(, document.body); }; const Extension = () => { const [loading, setLoading] = useState(true); const [metrics, setMetrics] = useState(null); const [error, setError] = useState(false); const [timeRange, setTimeRange] = useState('7d'); const fetchMetrics = async (range) => { setLoading(true); setError(false); const collectionId = shopify.data.selected[0].id; try { const response = await fetch('https://your-app.com/api/collection-analytics', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({collectionId, timeRange: range}), }); if (response.ok) { const data = await response.json(); setMetrics(data); } else { setError(true); } } catch (err) { setError(true); } finally { setLoading(false); } }; useEffect(() => { fetchMetrics(timeRange); }, [timeRange]); return ( {error && ( Unable to load analytics data. )} setTimeRange(e.currentTarget.value)} options={[ {value: '7d', label: 'Last 7 days'}, {value: '30d', label: 'Last 30 days'}, {value: '90d', label: 'Last 90 days'}, ]} /> {loading ? ( ) : metrics && ( Total Sales {metrics.totalSales || '$0.00'} Page Views {metrics.pageViews || '0'} Conversion Rate {metrics.conversionRate || '0%'} 2 ? 'success' : 'warning'}> {metrics.conversionRate > 2 ? 'Above avg' : 'Below avg'} )} ); }; ``` * #### ##### Description Create a block extension that displays out-of-stock products within a collection. This example demonstrates using the \[direct API]\(/docs/api/admin-extensions/2026-01#direct-api-access) to query collection products and their inventory status. ##### jsx ```jsx import {render} from 'preact'; import {useState, useEffect} from 'preact/hooks'; export default async () => { render(, document.body); }; const Extension = () => { const [loading, setLoading] = useState(true); const [outOfStock, setOutOfStock] = useState([]); const [error, setError] = useState(false); useEffect(() => { fetchCollectionProducts(); }, []); const fetchCollectionProducts = async () => { const collectionId = shopify.data.selected[0].id; const query = ` query GetCollectionProducts($id: ID!) { collection(id: $id) { title products(first: 50) { nodes { id title totalInventory featuredImage { url } } } } } `; try { const response = await fetch('shopify:admin/api/graphql.json', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({query, variables: {id: collectionId}}), }); const {data} = await response.json(); const products = data?.collection?.products?.nodes || []; const outOfStockProducts = products.filter(p => p.totalInventory <= 0); setOutOfStock(outOfStockProducts); } catch (err) { setError(true); } finally { setLoading(false); } }; if (loading) { return ( ); } return ( {error && ( Failed to load inventory data. )} {!error && outOfStock.length === 0 && ( All products in this collection are in stock! )} {!error && outOfStock.length > 0 && ( {outOfStock.map((product) => ( {product.title} Out of Stock ))} )} Showing inventory status for collection products ); }; ``` *** ## Collection index targets Use [action targets](https://shopify.dev/docs/api/admin-extensions/2026-01#building-your-extension) to extend the collection index page with bulk operations and workflows that help merchants manage multiple collections efficiently. ### Collection index action target `admin.collection-index.action.render` Renders an admin action extension on the collection index page. Merchants can access this extension from the **More actions** menu. Use this target to provide workflows that operate on collection data, such as syncing with external systems, exporting collection information, or managing credit terms. Extensions at this target can access collection data through the `data` property in the [Action Extension API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/core-apis/action-extension-api). The action renders in a modal overlay, providing space for multi-step workflows, forms, and confirmations. ### Support Components (55) APIs (1) ### Supported components * [Admin action](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/settings-and-templates/admin-action) * [Avatar](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/avatar) * [Badge](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/badge) * [Banner](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/banner) * [Box](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/box) * [Button](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/button) * [Button group](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/button-group) * [Checkbox](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/checkbox) * [Chip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/chip) * Choice * [Choice list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/choice-list) * [Clickable](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/clickable) * [Clickable chip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/clickable-chip) * [Color field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/color-field) * [Color picker](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/color-picker) * [Date field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/date-field) * [Date picker](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/date-picker) * [Divider](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/divider) * [Drop zone](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/drop-zone) * [Email field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/email-field) * [Grid](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/grid) * Grid item * [Heading](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/heading) * [Icon](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/icon) * [Image](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/image) * [Link](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/link) * List item * [Menu](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/actions/menu) * [Money field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/money-field) * [Number field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/number-field) * Option * Option group * [Ordered list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/ordered-list) * [Paragraph](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/paragraph) * [Password field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/password-field) * [Query container](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/query-container) * [Search field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/search-field) * [Section](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/section) * [Select](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/select) * [Spinner](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/feedback-and-status-indicators/spinner) * [Stack](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/stack) * [Switch](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/switch) * [Table](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/table) * Table body * Table cell * Table header * Table header row * Table row * [Text](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/text) * [Text area](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/text-area) * [Text field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/text-field) * [Thumbnail](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/media-and-visuals/thumbnail) * [Tooltip](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/typography-and-content/tooltip) * [Url field](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/forms/url-field) * [Unordered list](https://shopify.dev/docs/api/admin-extensions/2026-01/web-components/layout-and-structure/unordered-list) ### Available APIs * [Action Extension API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/core-apis/action-extension-api) Examples ### Examples * #### ##### Description Add an action extension that generates a comprehensive report of all collections in the store. This example demonstrates calling your app backend to compile collection statistics, product counts, and inventory totals across the entire catalog. ##### jsx ```jsx import {render} from 'preact'; import {useState} from 'preact/hooks'; export default async () => { render(, document.body); }; const Extension = () => { const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const [error, setError] = useState(false); const [includeVariants, setIncludeVariants] = useState(true); const [includePricing, setIncludePricing] = useState(true); const handleExport = async () => { setLoading(true); setError(false); try { const response = await fetch('https://your-app.com/api/collections/export', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ includeVariants, includePricing, }), }); if (response.ok) { const blob = await response.blob(); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'collection-products.csv'; link.click(); setSuccess(true); shopify.close(); } else { setError(true); } } catch (err) { setError(true); } finally { setLoading(false); } }; return ( {success && ( Export complete! Your download should start automatically. )} {error && ( Failed to export products. Please try again. )} setIncludeVariants(e.currentTarget.checked)} /> setIncludePricing(e.currentTarget.checked)} /> The CSV will include product titles, SKUs, inventory, and images. {loading ? 'Exporting...' : 'Export to CSV'} shopify.close()}> Cancel ); }; ``` * #### ##### Description Add an action extension that pushes all collections to an external marketing platform. This example demonstrates using the \[GraphQL Admin API]\(/docs/api/admin-graphql) to retrieve all collection details before syncing to a third-party system. ##### jsx ```jsx import {render} from 'preact'; import {useState} from 'preact/hooks'; export default async () => { render(, document.body); }; const Extension = () => { const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const [error, setError] = useState(null); const [platform, setPlatform] = useState('contentful'); const [includeProducts, setIncludeProducts] = useState(true); const handleSync = async () => { setLoading(true); setError(null); try { const response = await fetch('shopify:admin/api/graphql.json', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ query: `query GetCollections($ids: [ID!]!) { nodes(ids: $ids) { ... on Collection { id title description handle image { url altText } productsCount { count } } } }`, variables: { ids: shopify.data.selected.map(item => item.id) } }), }); const {data, errors} = await response.json(); if (errors) { throw new Error(errors[0].message); } const collections = data.nodes.filter(Boolean); console.log(`Syncing ${collections.length} collections to ${platform}`, { includeProducts, collections }); setSuccess(true); shopify.close(); } catch (err) { setError(err.message || 'Failed to sync collections'); } finally { setLoading(false); } }; const selectedCount = shopify.data.selected.length; return ( {success && ( Successfully synced {selectedCount} collection(s) to CMS! )} {error && ( {error} )} {selectedCount} collection(s) selected for sync setPlatform(e.currentTarget.value)} options={[ {value: 'contentful', label: 'Contentful'}, {value: 'sanity', label: 'Sanity'}, {value: 'strapi', label: 'Strapi'} ]} /> setIncludeProducts(e.currentTarget.checked)} /> {loading ? 'Syncing...' : `Sync to ${platform}`} shopify.close()}> Cancel ); }; ``` ### Collection index action (should render) target `admin.collection-index.action.should-render` Controls the render state of an admin action extension on the collection index page. Use this target to conditionally show or hide your action extension based on the collection's properties, such as status, configuration, or specific business requirements. This target returns a boolean value that determines whether the corresponding action extension appears in the **More actions** menu. The extension evaluates each time the page loads. ### Support Components (0) APIs (1) ### Supported components \- ### Available APIs * [Should Render API](https://shopify.dev/docs/api/admin-extensions/2026-01/target-apis/utility-apis/should-render-api) Examples ### Examples * #### ##### Description Show the action only when the store has collection analytics enabled in your app's tracking system. ##### jsx ```jsx export default async () => { const selectedCollections = shopify.data.selected; if (!selectedCollections || selectedCollections.length === 0) { return { display: false }; } const collectionIds = selectedCollections.map(item => item.id); try { const response = await fetch('https://your-app.com/api/collections/check-tracking', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ collectionIds, shop: shopify.data.shop.id, }), }); if (!response.ok) { return { display: false }; } const result = await response.json(); // Show action if at least one collection has performance tracking enabled return { display: result.hasTrackedCollections }; } catch (err) { console.error('Failed to check collection tracking status:', err); return { display: false }; } }; ``` * #### ##### Description Add an action extension that only displays when the store has collections containing products with low inventory, using the \[GraphQL Admin API]\(/docs/api/admin-graphql) to check store-wide inventory status. ##### jsx ```jsx export default async () => { const collectionId = shopify.data.selected[0].id; try { const response = await fetch('shopify:admin/api/graphql.json', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: `query GetCollectionProducts($id: ID!) { collection(id: $id) { products(first: 50) { nodes { totalInventory } } } }`, variables: { id: collectionId }, }), }); const { data } = await response.json(); if (!data?.collection?.products?.nodes) { return { display: false }; } const hasOutOfStock = data.collection.products.nodes.some( (product) => product.totalInventory === 0 ); return { display: hasOutOfStock }; } catch (err) { console.error('Error checking collection inventory:', err); return { display: false }; } }; ``` *** ## Best practices * **Account for automated collections:** Collections can be manual (fixed product list) or [automated](https://shopify.dev/docs/api/admin-graphql/latest/objects/Collection#field-Collection.fields.ruleSet) (rule-based). When displaying collection analytics or inventory status, remember that automated collection membership changes when products are added/removed or when their properties change. Check `ruleSet` to determine collection type. * **Handle large product sets with pagination:** Collections can contain thousands of products. When fetching collection products, use [cursor-based pagination](https://shopify.dev/docs/api/usage/pagination-graphql) (for example, 50 products per page) and implement progressive loading for collections with more than 100 products to avoid timeouts and high [query costs](https://shopify.dev/docs/api/usage/rate-limits). * **Show product rankings within collections:** If your extension displays collection analytics, consider showing product performance rankings within the collection. This helps merchants optimize product ordering and identify which items drive collection sales. * **Manage products in multiple collections:** Products often belong to multiple collections. When building extensions that modify product [metafields](https://shopify.dev/docs/apps/build/metafields) or tags based on collection membership, allow merchants to specify whether changes should be collection-specific or apply globally. * **Consider collection availability:** Collections can be published to specific sales channels (online store, POS, and others). When syncing collections to external systems, include [publication](https://shopify.dev/docs/api/admin-graphql/latest/objects/Publication) context so the external system knows where the collection is available. *** ## Limitations * **Single target per module:** Each `[[extensions.targeting]]` entry in your [TOML configuration](https://shopify.dev/docs/api/admin-extensions/2026-01#configuration) maps one target to one module file. * **Product pagination:** The GraphQL API limits product queries to a [maximum of 250 items](https://shopify.dev/docs/api/usage/pagination-graphql) per request. * **Smart collection restrictions:** Smart collections reject manual product additions. GraphQL returns an error: "Can't manually add products to a smart collection." * **Block target visibility:** Block extensions must be manually [added and pinned](https://help.shopify.com/manual/apps/working-with-apps#add-app-blocks-to-your-shopify-admin) by merchants before they appear. * **Block collapse behavior:** Returning `null` from a block extension collapses the block rather than removing it from the page. Blocks can't be fully hidden at runtime. ***