Skip to content
Closed
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
32 changes: 32 additions & 0 deletions admin-search-data/README.md.liquid
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 4 additions & 0 deletions admin-search-data/locales/en.default.json.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "{{ name }}",
"description": "Search extension for your app"
}
4 changes: 4 additions & 0 deletions admin-search-data/locales/fr.json.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "{{ name }}",
"description": "Extension de recherche pour votre application"
}
9 changes: 9 additions & 0 deletions admin-search-data/package.json.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "{{ handle }}",
"private": true,
"version": "1.0.0",
"license": "UNLICENSED",
"dependencies": {
"@shopify/ui-extensions": "2025.10.x"
}
}
14 changes: 14 additions & 0 deletions admin-search-data/shopify.extension.toml.liquid
Original file line number Diff line number Diff line change
@@ -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"
45 changes: 45 additions & 0 deletions admin-search-data/src/SearchData.liquid
Original file line number Diff line number Diff line change
@@ -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<SearchOutput>{%- 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<void> =>{%- else -%} async () =>{%- endif %} {
shopify.tools.register('search', search);
};
77 changes: 77 additions & 0 deletions admin-search-data/src/tools.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
}
}
]
10 changes: 10 additions & 0 deletions admin-search-data/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2020",
"checkJs": true,
"allowJs": true,
"moduleResolution": "node",
"esModuleInterop": true,
"noEmit": true
}
}
10 changes: 10 additions & 0 deletions admin-search-data/tsconfig.json.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2020",
"checkJs": true,
"allowJs": true,
"moduleResolution": "node",
"esModuleInterop": true,
"noEmit": true
}
}