From b350f97b0533eb6d8e2e1ced0b0c9854dfa0c59c Mon Sep 17 00:00:00 2001 From: Bill Fienberg Date: Tue, 6 Jan 2026 17:12:17 -0600 Subject: [PATCH] add initial admin-search-data template --- admin-search-data/README.md.liquid | 32 ++++++++ .../locales/en.default.json.liquid | 4 + admin-search-data/locales/fr.json.liquid | 4 + admin-search-data/package.json.liquid | 9 +++ .../shopify.extension.toml.liquid | 14 ++++ admin-search-data/src/SearchData.liquid | 45 +++++++++++ admin-search-data/src/tools.json | 77 +++++++++++++++++++ admin-search-data/tsconfig.json | 10 +++ admin-search-data/tsconfig.json.liquid | 10 +++ 9 files changed, 205 insertions(+) create mode 100644 admin-search-data/README.md.liquid create mode 100644 admin-search-data/locales/en.default.json.liquid create mode 100644 admin-search-data/locales/fr.json.liquid create mode 100644 admin-search-data/package.json.liquid create mode 100644 admin-search-data/shopify.extension.toml.liquid create mode 100644 admin-search-data/src/SearchData.liquid create mode 100644 admin-search-data/src/tools.json create mode 100644 admin-search-data/tsconfig.json create mode 100644 admin-search-data/tsconfig.json.liquid diff --git a/admin-search-data/README.md.liquid b/admin-search-data/README.md.liquid new file mode 100644 index 00000000..a41c692c --- /dev/null +++ b/admin-search-data/README.md.liquid @@ -0,0 +1,32 @@ +# {{ name }} + +{{ description }} + +--- + +## Get started with this extension + +This extension provides search functionality for the Shopify Admin. After installation, your app's search results will appear in Admin search. + +### Key files + +- `src/SearchData.{{ srcFileExtension }}` - Main extension code that registers the search tool +- `src/tools.json` - Schema definition for the search tool inputs and outputs + +### How it works + +1. The extension registers a `search` tool using `shopify.tools.register()` +2. When a user searches in the Admin, your search function is called with the query +3. Your function returns results matching the schema defined in `tools.json` + +### Customizing the search + +Edit `src/SearchData.{{ srcFileExtension }}` to implement your search logic: + +1. Fetch data from your app's backend or API +2. Filter/search the data based on the `query` input +3. Return results in the expected format with pagination info + +### Testing locally + +Run `shopify app dev` to test your extension in development mode. diff --git a/admin-search-data/locales/en.default.json.liquid b/admin-search-data/locales/en.default.json.liquid new file mode 100644 index 00000000..4fbfab2f --- /dev/null +++ b/admin-search-data/locales/en.default.json.liquid @@ -0,0 +1,4 @@ +{ + "name": "{{ name }}", + "description": "Search extension for your app" +} diff --git a/admin-search-data/locales/fr.json.liquid b/admin-search-data/locales/fr.json.liquid new file mode 100644 index 00000000..d280be39 --- /dev/null +++ b/admin-search-data/locales/fr.json.liquid @@ -0,0 +1,4 @@ +{ + "name": "{{ name }}", + "description": "Extension de recherche pour votre application" +} diff --git a/admin-search-data/package.json.liquid b/admin-search-data/package.json.liquid new file mode 100644 index 00000000..dc581be1 --- /dev/null +++ b/admin-search-data/package.json.liquid @@ -0,0 +1,9 @@ +{ + "name": "{{ handle }}", + "private": true, + "version": "1.0.0", + "license": "UNLICENSED", + "dependencies": { + "@shopify/ui-extensions": "2025.10.x" + } +} diff --git a/admin-search-data/shopify.extension.toml.liquid b/admin-search-data/shopify.extension.toml.liquid new file mode 100644 index 00000000..d89b1b29 --- /dev/null +++ b/admin-search-data/shopify.extension.toml.liquid @@ -0,0 +1,14 @@ +api_version = "2025-10" + +[[extensions]] +# Change the merchant-facing name of the extension in locales/en.default.json +name = "t:name" +handle = "{{ handle }}" +type = "ui_extension" +{% if uid %}uid = "{{ uid }}"{% endif %} +description = "t:description" + +[[extensions.targeting]] +module = "./src/SearchData.{{ srcFileExtension }}" +target = "admin.app.search.data" +tools = "src/tools.json" diff --git a/admin-search-data/src/SearchData.liquid b/admin-search-data/src/SearchData.liquid new file mode 100644 index 00000000..af8480f8 --- /dev/null +++ b/admin-search-data/src/SearchData.liquid @@ -0,0 +1,45 @@ +{%- if flavor contains 'typescript' -%} +interface SearchInput { + query?: string; + after?: string; + first?: number; +} + +interface SearchResult { + id: string; + type: string; + url: string; + title: string; +} + +interface SearchOutput { + results: SearchResult[]; + pageInfo: { + hasNextPage: boolean; + hasPreviousPage: boolean; + startCursor: string | null; + endCursor: string | null; + }; +} +{%- endif %} + +async function search(input{%- if flavor contains 'typescript' -%}: SearchInput{%- endif -%}){%- if flavor contains 'typescript' -%}: Promise{%- endif %} { + const {query = '', first = 10, after} = input; + + // TODO: Implement your search logic here + // This is a placeholder that returns empty results + + return { + results: [], + pageInfo: { + hasNextPage: false, + hasPreviousPage: false, + startCursor: null, + endCursor: null, + }, + }; +} + +export default {%- if flavor contains 'typescript' -%} async (): Promise =>{%- else -%} async () =>{%- endif %} { + shopify.tools.register('search', search); +}; diff --git a/admin-search-data/src/tools.json b/admin-search-data/src/tools.json new file mode 100644 index 00000000..4ce2d71c --- /dev/null +++ b/admin-search-data/src/tools.json @@ -0,0 +1,77 @@ +[ + { + "name": "search", + "description": "Search for resources", + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Search query string" + }, + "after": { + "type": "string", + "description": "Cursor for pagination - returns elements after this cursor" + }, + "first": { + "type": "integer", + "description": "Number of results to return (default: 10)" + } + }, + "required": [] + }, + "outputSchema": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for the result" + }, + "type": { + "type": "string", + "description": "The type/category of the result" + }, + "url": { + "type": "string", + "description": "URL to view or edit the resource" + }, + "title": { + "type": "string", + "description": "Display title for the result" + } + }, + "required": ["id", "type"] + } + }, + "pageInfo": { + "type": "object", + "properties": { + "hasNextPage": { + "type": "boolean", + "description": "Whether there are more results available" + }, + "hasPreviousPage": { + "type": "boolean", + "description": "Whether there are previous results available" + }, + "startCursor": { + "type": "string", + "nullable": true, + "description": "Cursor for the first item in results" + }, + "endCursor": { + "type": "string", + "nullable": true, + "description": "Cursor for the last item in results" + } + } + } + } + } + } +] diff --git a/admin-search-data/tsconfig.json b/admin-search-data/tsconfig.json new file mode 100644 index 00000000..a5da8e40 --- /dev/null +++ b/admin-search-data/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "checkJs": true, + "allowJs": true, + "moduleResolution": "node", + "esModuleInterop": true, + "noEmit": true + } +} diff --git a/admin-search-data/tsconfig.json.liquid b/admin-search-data/tsconfig.json.liquid new file mode 100644 index 00000000..a5da8e40 --- /dev/null +++ b/admin-search-data/tsconfig.json.liquid @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "checkJs": true, + "allowJs": true, + "moduleResolution": "node", + "esModuleInterop": true, + "noEmit": true + } +}