Hello @manish-sharma coded my plugin locally settings are ok as well as input :
Similar to products and collections I want to search and filter though a list of templates fetched through asset RESTAdmin endpoint : Asset
…But still templates failed to fetch
I tried to refactor it but I think I spotted the issue in the console

Is there a way around this CORS blocked error?
here is the plug in code
import { registerCommercePlugin } from '@builder.io/plugin-tools';
import Client from 'shopify-buy';
import pkg from '../package.json';
import appState from '@builder.io/app-context';
import { getDataConfig } from './data-plugin';
/**
* Helper to fetch Shopify Admin API JSON
*/
async function adminFetchJSON(opts: {
storeDomain: string;
apiVersion: string;
adminAccessToken: string;
path: string;
}) {
const url = `https://${opts.storeDomain}/admin/api/${opts.apiVersion}${opts.path}`;
const res = await fetch(url, {
headers: {
'X-Shopify-Access-Token': opts.adminAccessToken,
'Content-Type': 'application/json',
},
});
if (!res.ok) {
throw new Error(`Admin API error ${res.status}`);
}
return res.json();
}
function normalizeApiVersion(version?: string) {
return version || '2025-07';
}
registerCommercePlugin(
{
name: 'Shopify',
id: pkg.name,
settings: [
{
name: 'storefrontAccessToken',
type: 'string',
helperText: 'Required to fetch storefront product data',
required: true,
},
{
name: 'storeDomain',
type: 'text',
helperText: 'Your entire store domain, such as "your-store.myshopify.com"',
required: true,
},
{
name: 'apiVersion',
type: 'text',
helperText: 'Your Shopify API version, such as "2025-07"',
},
{
name: 'adminAccessToken',
type: 'string',
helperText: 'Private Admin API access token (for template JSON)',
required: true,
},
{
name: 'themeId',
type: 'string',
helperText: 'Theme ID to fetch templates from',
required: true,
},
],
ctaText: `Connect your Shopify custom app`,
},
async settings => {
const client = Client.buildClient({
storefrontAccessToken: settings.get('storefrontAccessToken'),
domain: settings.get('storeDomain'),
apiVersion: '2025-07',
});
const service: any = {
product: {
async findById(id: string) {
return client.product.fetch(id);
},
async findByHandle(handle: string) {
return client.product.fetchByHandle(handle);
},
async search(search: string) {
const sources =
(await client.product.fetchQuery({
query: search ? `title:*${search}*` : '',
sortKey: 'TITLE',
first: 250,
})) || [];
return sources.map((src: any) => ({
...src,
image: src.image || src.images?.[0],
}));
},
getRequestObject(id: string) {
return {
'@type': '@builder.io/core:Request' as const,
request: {
url: `${appState.config.apiRoot()}/api/v1/shopify/storefront/product/${id}?apiKey=${
appState.user.apiKey
}&pluginId=${pkg.name}`,
},
options: { product: id },
};
},
},
collection: {
async findById(id: string) {
return client.collection.fetch(id);
},
async findByHandle(handle: string) {
return client.collection.fetchByHandle(handle);
},
async search(search: string) {
return client.collection.fetchQuery({
query: search ? `title:*${search}*` : '',
sortKey: 'TITLE',
first: 250,
});
},
getRequestObject(id: string) {
return {
'@type': '@builder.io/core:Request' as const,
request: {
url: `${appState.config.apiRoot()}/api/v1/shopify/storefront/collection/${id}?apiKey=${
appState.user.apiKey
}&pluginId=${pkg.name}`,
},
options: { collection: id },
};
},
},
template: {
async findById(templateName: string) {
const themeId = settings.get('themeId');
const token = settings.get('adminAccessToken');
const storeDomain = settings.get('storeDomain');
const apiVersion = normalizeApiVersion(settings.get('apiVersion'));
const path = `/themes/${encodeURIComponent(themeId)}/assets.json?asset[key]=templates/${encodeURIComponent(
templateName
)}.json`;
const data = await adminFetchJSON({
storeDomain,
apiVersion,
adminAccessToken: token,
path,
});
const parsed = JSON.parse(data?.asset?.value || '{}');
// Store template JSON globally so sections can access it
// appState.globalState.templateJson = parsed;
console.log('Parsed template JSON:', parsed);
return {
id: templateName,
title: templateName,
name: templateName,
json: parsed,
sections: parsed?.sections || {},
};
},
async search(search: string = '') {
const themeId = settings.get('themeId');
const token = settings.get('adminAccessToken');
const storeDomain = settings.get('storeDomain');
const apiVersion = normalizeApiVersion(settings.get('apiVersion'));
const path = `/themes/${encodeURIComponent(themeId)}/assets.json`;
const data = await adminFetchJSON({
storeDomain,
apiVersion,
adminAccessToken: token,
path,
});
const assets: Array<{ key: string }> = data?.assets || [];
let templates = assets
.map(a => a.key)
.filter(key => key.startsWith('templates/') && key.endsWith('.json'));
if (search) {
const re = new RegExp(search, 'i');
templates = templates.filter(k => re.test(k));
}
return templates.map(key => {
const base = key.replace(/^templates\//, '').replace(/\.json$/, '');
return { id: base, title: base };
});
},
getRequestObject(templateName: string) {
// Builder server proxy endpoint — still fine to use /storefront/ here
return {
'@type': '@builder.io/core:Request' as const,
request: {
url: `${appState.config.apiRoot()}/api/lastest/shopify/storefront/template/${templateName}?apiKey=${
appState.user.apiKey
}&pluginId=${pkg.name}`,
},
options: { template: templateName },
};
},
},
};
appState.registerDataPlugin(getDataConfig(service as any));
return service;
}
);