@veyralabs/skills 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,216 @@
1
+ # MCP Queries — shopify-store Reference
2
+
3
+ Ready-to-use GraphQL queries for Mode A (shopify-mcp connected).
4
+ All queries use the Admin API via the shopify-mcp `graphql` tool.
5
+
6
+ ---
7
+
8
+ ## Products
9
+
10
+ ### Get all products with SEO fields
11
+ ```graphql
12
+ query GetProducts($cursor: String) {
13
+ products(first: 250, after: $cursor) {
14
+ pageInfo { hasNextPage endCursor }
15
+ nodes {
16
+ id
17
+ title
18
+ handle
19
+ status
20
+ descriptionHtml
21
+ seo { title description }
22
+ images(first: 5) {
23
+ nodes { id url altText }
24
+ }
25
+ variants(first: 100) {
26
+ nodes { id title sku price availableForSale }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### Products missing SEO data
34
+ ```graphql
35
+ query ProductsSEOAudit {
36
+ products(first: 250, query: "status:active") {
37
+ nodes {
38
+ id
39
+ title
40
+ seo { title description }
41
+ images(first: 1) {
42
+ nodes { altText }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Collections
52
+
53
+ ### Full collection structure
54
+ ```graphql
55
+ query GetCollections {
56
+ collections(first: 100) {
57
+ nodes {
58
+ id
59
+ title
60
+ handle
61
+ sortOrder
62
+ productsCount { count }
63
+ seo { title description }
64
+ image { altText url }
65
+ ruleSet {
66
+ rules { column relation condition }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Navigation (Menus)
76
+
77
+ ```graphql
78
+ query GetMenus {
79
+ menus(first: 10) {
80
+ nodes {
81
+ id
82
+ title
83
+ handle
84
+ items {
85
+ id
86
+ title
87
+ url
88
+ type
89
+ items {
90
+ id
91
+ title
92
+ url
93
+ type
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Orders (last 90 days)
104
+
105
+ ```graphql
106
+ query GetOrders {
107
+ orders(first: 250, query: "created_at:>2025-01-01") {
108
+ nodes {
109
+ id
110
+ totalPriceSet { shopMoney { amount currencyCode } }
111
+ lineItems(first: 10) {
112
+ nodes { quantity title sku }
113
+ }
114
+ customer { id email numberOfOrders }
115
+ createdAt
116
+ cancelledAt
117
+ financialStatus
118
+ fulfillmentStatus
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Metafields
127
+
128
+ ### Get product metafields
129
+ ```graphql
130
+ query GetProductMetafields($id: ID!) {
131
+ product(id: $id) {
132
+ metafields(first: 20) {
133
+ nodes {
134
+ namespace
135
+ key
136
+ value
137
+ type
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### Set SEO metafield
145
+ ```graphql
146
+ mutation SetMetafield($metafields: [MetafieldsSetInput!]!) {
147
+ metafieldsSet(metafields: $metafields) {
148
+ metafields { key value }
149
+ userErrors { field message }
150
+ }
151
+ }
152
+ ```
153
+ Variables:
154
+ ```json
155
+ {
156
+ "metafields": [{
157
+ "ownerId": "gid://shopify/Product/123",
158
+ "namespace": "seo",
159
+ "key": "description",
160
+ "value": "Your SEO description here",
161
+ "type": "single_line_text_field"
162
+ }]
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Installed Apps (via App Installations)
169
+
170
+ ```graphql
171
+ query GetInstalledApps {
172
+ appInstallations(first: 50) {
173
+ nodes {
174
+ app {
175
+ title
176
+ handle
177
+ developerName
178
+ pricingSummary
179
+ }
180
+ launchUrl
181
+ uninstallUrl
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Shopify Analytics (basic)
190
+
191
+ ```graphql
192
+ query GetShopInfo {
193
+ shop {
194
+ name
195
+ myshopifyDomain
196
+ plan { displayName partnerDevelopment }
197
+ currencyCode
198
+ timezoneAbbreviation
199
+ ianaTimezone
200
+ }
201
+ }
202
+ ```
203
+
204
+ For revenue/conversion analytics, use the Reports API:
205
+ ```graphql
206
+ query GetReports {
207
+ reports(first: 10, query: "report_type:custom") {
208
+ nodes {
209
+ id
210
+ name
211
+ category
212
+ shopifyQL
213
+ }
214
+ }
215
+ }
216
+ ```
@@ -0,0 +1,266 @@
1
+ # Product Optimization — shopify-store Reference
2
+
3
+ Title formulas, description frameworks, and image standards for Shopify product pages.
4
+
5
+ ---
6
+
7
+ ## Title Formulas
8
+
9
+ ### Formula by product type
10
+
11
+ **Apparel:**
12
+ ```
13
+ [Product Name] — [Key Attribute] | [Brand]
14
+ Blue Linen Shirt — Relaxed Fit | Studio Name
15
+ Oversized Hoodie — 400gsm Cotton | Brand
16
+ ```
17
+
18
+ **Electronics / tech:**
19
+ ```
20
+ [Brand] [Product Name] [Model/Key Spec]
21
+ Brand Wireless Headphones ANC Pro 45hr
22
+ ```
23
+
24
+ **Home goods / furniture:**
25
+ ```
26
+ [Product Name] — [Material/Style] — [Size if relevant]
27
+ Oak Dining Table — Solid Wood — 160cm
28
+ Linen Throw Pillow — Natural — 45x45cm
29
+ ```
30
+
31
+ **Beauty / skincare:**
32
+ ```
33
+ [Product Name] — [Key Ingredient/Benefit] | [Brand]
34
+ Vitamin C Serum — Brightening 20% | Brand
35
+ ```
36
+
37
+ **Food / consumables:**
38
+ ```
39
+ [Product Name] — [Size/Format/Origin]
40
+ Organic Olive Oil — 500ml Cold Press
41
+ Colombian Coffee — Medium Roast 250g
42
+ ```
43
+
44
+ ### Title rules
45
+ - 50-70 characters (shows fully in Google SERP and Shopify search)
46
+ - Lead with product name, not brand (unless brand is the purchase driver)
47
+ - Include the one attribute buyers filter by most (color, size, material)
48
+ - No: "NEW", "SALE", "BEST SELLER", "!", "100% authentic"
49
+ - No: all caps
50
+ - No: variant info in title (size S/M/L goes in variants, not title)
51
+
52
+ ---
53
+
54
+ ## Meta Title Formulas
55
+
56
+ The meta title is separate from the product title in Shopify (Admin → SEO section).
57
+
58
+ ```
59
+ [Product Name] [Key Attribute] — Buy Online | [Brand]
60
+ [Primary Keyword] — [Secondary Keyword] | [Brand]
61
+ ```
62
+
63
+ Examples:
64
+ ```
65
+ Linen Relaxed Shirt — Men's Summer Fashion | Studio Name
66
+ Wireless Noise Cancelling Headphones | Brand
67
+ Organic Olive Oil 500ml — Cold Pressed | Store Name
68
+ ```
69
+
70
+ Rules:
71
+ - 50-60 characters (Google truncates at ~60)
72
+ - Include primary keyword near the front
73
+ - Include brand at end (recognition, not keyword — separator `|` or `—`)
74
+ - Different from the product title (if they're identical, one is wasted)
75
+
76
+ ---
77
+
78
+ ## Description Framework
79
+
80
+ ### SPECS → STORY → SOCIAL PROOF structure
81
+
82
+ ```
83
+ [Opening line: main benefit or use case — 1 sentence]
84
+
85
+ [Specs block: what it's made of, dimensions, key features — short bullets]
86
+
87
+ [Story paragraph: who it's for, when to use it, why it matters — 2-3 sentences]
88
+
89
+ [Trust closer: shipping, returns, sizing guide link — 1 sentence]
90
+ ```
91
+
92
+ ### Example (apparel)
93
+
94
+ ```html
95
+ <p>A linen shirt built for warm weather — breathable, lightweight, and gets better with every wash.</p>
96
+
97
+ <ul>
98
+ <li>100% European linen</li>
99
+ <li>Relaxed fit, fits true to size</li>
100
+ <li>Available in 8 colors</li>
101
+ <li>Machine washable at 30°C</li>
102
+ </ul>
103
+
104
+ <p>Designed for easy summer days — works equally well with shorts or tailored trousers.
105
+ The fabric softens naturally over time without losing its shape.</p>
106
+
107
+ <p>Free shipping on orders over €50. 30-day free returns. <a href="/pages/size-guide">Size guide</a>.</p>
108
+ ```
109
+
110
+ ### Example (electronics)
111
+
112
+ ```html
113
+ <p>45 hours of active noise cancellation, zero compromise on sound quality.</p>
114
+
115
+ <ul>
116
+ <li>ANC: -35dB noise reduction</li>
117
+ <li>Battery: 45hr ANC on, 60hr ANC off</li>
118
+ <li>Charging: USB-C, 15min = 5hr playback</li>
119
+ <li>Connectivity: Bluetooth 5.3, multipoint (2 devices simultaneously)</li>
120
+ <li>Weight: 248g</li>
121
+ </ul>
122
+
123
+ <p>Designed for long work sessions and travel. The over-ear cushions are memory foam —
124
+ they seal out noise without pressure points after hours of wear.</p>
125
+
126
+ <p>2-year warranty. Free returns within 30 days. Ships in 1-2 business days.</p>
127
+ ```
128
+
129
+ ### Description rules
130
+ - Minimum 150 characters, aim for 300-500 characters
131
+ - First 160 characters become the meta description fallback — make them strong
132
+ - Lead with benefit, not feature ("stays cool" not "made of linen")
133
+ - Bullets for specs, prose for story — mix formats
134
+ - Include dimensions/weight for anything where size matters
135
+ - No fluff: "quality product", "you'll love it", "great for everyone"
136
+ - No generic manufacturer text — rewrite it
137
+
138
+ ---
139
+
140
+ ## Meta Description Formulas
141
+
142
+ ```
143
+ [Main benefit]. [Key specs/features]. [Trust signal or CTA].
144
+ ```
145
+
146
+ Examples:
147
+ ```
148
+ Breathable linen shirt perfect for summer. Available in 8 colors, sizes XS-XXL. Free shipping over €50.
149
+ (134 chars)
150
+
151
+ Noise cancelling headphones with 45hr battery. Bluetooth 5.3, USB-C fast charge. 2-year warranty included.
152
+ (106 chars)
153
+
154
+ Cold-pressed organic olive oil from Spanish groves. 500ml bottle, harvested November 2024. Free delivery over €30.
155
+ (113 chars)
156
+ ```
157
+
158
+ Rules:
159
+ - 120-160 characters
160
+ - Unique per product (not the same as title)
161
+ - Include a purchase-trigger: price signal, shipping benefit, time signal, social proof
162
+ - No clickbait ("You won't believe...")
163
+ - Ends with implicit CTA or benefit
164
+
165
+ ---
166
+
167
+ ## Image Standards
168
+
169
+ ### Required images per product
170
+
171
+ | # | Image type | Purpose |
172
+ |---|-----------|---------|
173
+ | 1 | Hero / packshot | Main listing image — product centered, clean background |
174
+ | 2 | Lifestyle in context | Shows scale, use, aspiration |
175
+ | 3 | Detail / texture | Close-up of key material or feature |
176
+ | 4+ | Variant images | One per color/style variant |
177
+
178
+ ### Technical specs
179
+
180
+ | Spec | Recommended | Minimum |
181
+ |------|-------------|---------|
182
+ | Dimensions | 2048×2048px | 800×800px |
183
+ | Format | JPEG (80-85% quality) | — |
184
+ | Aspect ratio | 1:1 (square) | Consistent per product |
185
+ | Background (main image) | White #FFFFFF or very light gray | Clean neutral |
186
+ | File size | < 500KB after optimization | < 1MB |
187
+
188
+ ### Alt text formulas
189
+
190
+ ```
191
+ Main image: [Brand] [Product Name] [Key Attribute]
192
+ "Studio Name Blue Linen Shirt Relaxed Fit"
193
+
194
+ Lifestyle: [Product Name] [Context]
195
+ "Linen Shirt worn at outdoor dinner"
196
+
197
+ Detail: [Product Name] [What the detail shows]
198
+ "Linen Shirt fabric texture close-up"
199
+ ```
200
+
201
+ Rules:
202
+ - Describe what's in the image, not the product name repeated
203
+ - Don't start with "Image of" or "Photo of" — Google already knows it's an image
204
+ - Include color for variant images
205
+ - Max 125 characters
206
+
207
+ ### Variant images
208
+
209
+ Every color variant needs its own image — minimum the hero shot on the correct color.
210
+ Shopify auto-switches image when customer selects a color variant if images are tagged with variant.
211
+
212
+ In Shopify admin: product images → click image → assign to variant.
213
+
214
+ ---
215
+
216
+ ## Collection Descriptions
217
+
218
+ Short, keyword-rich, benefit-first:
219
+
220
+ ```
221
+ [What's in the collection — 1 sentence]. [Count or variety signal]. [Differentiator].
222
+ ```
223
+
224
+ Examples:
225
+ ```
226
+ Men's shirts in linen, cotton, and blends for every season. 40+ styles, new arrivals weekly.
227
+ Free shipping on orders over €50.
228
+ ```
229
+
230
+ ```
231
+ Wireless headphones from entry-level to professional grade. Tested and reviewed by our audio team.
232
+ 30-day trial period on every model.
233
+ ```
234
+
235
+ Rules:
236
+ - 2-4 sentences
237
+ - Include primary keyword naturally
238
+ - Avoid "our collection of" or "we offer" — lead with what's in it
239
+ - Update seasonally for campaign collections
240
+
241
+ ---
242
+
243
+ ## Variant Naming
244
+
245
+ ### Color naming
246
+
247
+ Use recognizable color names, not marketing names:
248
+ - "Navy Blue" not "Ocean Depths"
249
+ - "Forest Green" not "Emerald Whisper"
250
+ - "Off-White" not "Morning Mist"
251
+
252
+ Exception: luxury or high-differentiation brands where color naming IS part of the brand language.
253
+
254
+ ### Size naming
255
+
256
+ Consistent across catalog:
257
+ - Apparel: XS, S, M, L, XL, XXL (not Extra Small, Small, etc.)
258
+ - Shoes: numeric EU sizing (42, 43...) not US mixed
259
+ - Home: dimensions in cm or specific names ("Small / 45×45cm")
260
+
261
+ ### Option order
262
+
263
+ Color before size (most common filter order):
264
+ - Option 1: Color
265
+ - Option 2: Size
266
+ - Option 3: Material (if needed)
@@ -0,0 +1,165 @@
1
+ # SEO — Shopify-Specific Issues
2
+
3
+ Shopify has structural SEO issues that generic SEO guides miss. This covers the ones that actually matter.
4
+
5
+ ---
6
+
7
+ ## Duplicate Content (Shopify's biggest SEO problem)
8
+
9
+ ### The /products/ vs /collections/*/products/ problem
10
+
11
+ Shopify serves every product at two URLs:
12
+ - `https://store.com/products/blue-shirt`
13
+ - `https://store.com/collections/shirts/products/blue-shirt`
14
+
15
+ Shopify auto-canonicalizes collection-path URLs to the `/products/` URL. This is correct behavior — do not override it. But verify it's working:
16
+
17
+ ```html
18
+ <!-- Should appear on /collections/shirts/products/blue-shirt -->
19
+ <link rel="canonical" href="https://store.com/products/blue-shirt">
20
+ ```
21
+
22
+ If a custom theme or app overrides this, you get duplicate content penalties.
23
+
24
+ ### Tag pages getting indexed
25
+
26
+ Shopify creates URLs for every tag: `/collections/shirts/t-shirts`, `/collections/shirts/blue`.
27
+ These are thin pages with subset content — they dilute link equity and create duplicates.
28
+
29
+ Fix: add to `robots.txt` (Shopify 2.0 allows custom robots.txt):
30
+ ```
31
+ Disallow: /collections/*+*
32
+ ```
33
+ Or noindex via theme liquid:
34
+ ```liquid
35
+ {% if current_tags %}
36
+ <meta name="robots" content="noindex, follow">
37
+ {% endif %}
38
+ ```
39
+
40
+ ### Variant URLs
41
+
42
+ `/products/blue-shirt?variant=123456` creates near-duplicate pages per variant.
43
+ Shopify canonicalizes these to the main product URL automatically. Do not disable this.
44
+
45
+ ### Pagination
46
+
47
+ `/collections/shirts?page=2` — Shopify removed `rel="next"/"prev"` pagination support in 2019. Google handles these via `?page=N` parameters. Do not noindex paginated pages — you'll lose product indexing.
48
+
49
+ ---
50
+
51
+ ## Structured Data
52
+
53
+ ### Product schema (must-have)
54
+
55
+ Shopify themes should output this on every product page. Check if yours does:
56
+
57
+ ```html
58
+ <script type="application/ld+json">
59
+ {
60
+ "@context": "https://schema.org",
61
+ "@type": "Product",
62
+ "name": "{{ product.title }}",
63
+ "description": "{{ product.description | strip_html | escape }}",
64
+ "image": "{{ product.featured_image | img_url: '800x' }}",
65
+ "sku": "{{ product.selected_or_first_available_variant.sku }}",
66
+ "brand": {
67
+ "@type": "Brand",
68
+ "name": "{{ product.vendor }}"
69
+ },
70
+ "offers": {
71
+ "@type": "Offer",
72
+ "priceCurrency": "{{ cart.currency.iso_code }}",
73
+ "price": "{{ product.selected_or_first_available_variant.price | divided_by: 100.0 }}",
74
+ "availability": "{% if product.available %}https://schema.org/InStock{% else %}https://schema.org/OutOfStock{% endif %}",
75
+ "url": "{{ shop.url }}{{ product.url }}"
76
+ }
77
+ {% if product.metafields.reviews.rating %}
78
+ ,"aggregateRating": {
79
+ "@type": "AggregateRating",
80
+ "ratingValue": "{{ product.metafields.reviews.rating.value }}",
81
+ "reviewCount": "{{ product.metafields.reviews.rating_count }}"
82
+ }
83
+ {% endif %}
84
+ }
85
+ </script>
86
+ ```
87
+
88
+ ### BreadcrumbList (improves SERP appearance)
89
+
90
+ ```html
91
+ <script type="application/ld+json">
92
+ {
93
+ "@context": "https://schema.org",
94
+ "@type": "BreadcrumbList",
95
+ "itemListElement": [
96
+ { "@type": "ListItem", "position": 1, "name": "Home", "item": "{{ shop.url }}" },
97
+ { "@type": "ListItem", "position": 2, "name": "{{ collection.title }}", "item": "{{ shop.url }}{{ collection.url }}" },
98
+ { "@type": "ListItem", "position": 3, "name": "{{ product.title }}" }
99
+ ]
100
+ }
101
+ </script>
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Title and Meta Description Formulas
107
+
108
+ ### Product pages
109
+ ```
110
+ Title (50-60 chars): [Product Name] — [Key Attribute] | [Brand]
111
+ Example: "Blue Linen Shirt — Relaxed Fit | Mariano Studio"
112
+
113
+ Meta description (120-160 chars): [Benefit]. [Key features]. [CTA with differentiator].
114
+ Example: "Breathable linen shirt perfect for summer. Available in 8 colors, sizes XS-XXL. Free shipping over €50."
115
+ ```
116
+
117
+ ### Collection pages
118
+ ```
119
+ Title: [Collection Name] — [Category] | [Brand]
120
+ Example: "Men's Shirts — Linen & Cotton | Mariano Studio"
121
+
122
+ Meta description: [What's in the collection]. [Count/variety]. [Differentiator].
123
+ Example: "Browse our collection of 40+ men's shirts in linen, cotton, and blends. New arrivals weekly. Free returns."
124
+ ```
125
+
126
+ ### Homepage
127
+ ```
128
+ Title: [Brand] — [One-line value proposition]
129
+ Example: "Mariano Studio — Sustainable Linen Clothing for Men"
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Technical SEO Checklist
135
+
136
+ | Issue | Check | Fix |
137
+ |-------|-------|-----|
138
+ | Canonical tags | View source on product + collection URL | Should point to /products/ URL |
139
+ | Tag page indexation | Search site:store.com/collections inurl:t- | Add noindex or robots.txt disallow |
140
+ | Duplicate H1 | Check if theme puts product title in H1 twice | One H1 per page |
141
+ | Image alt texts | Inspect img tags on product pages | Fill via Shopify admin or bulk with metafields |
142
+ | Page speed | PageSpeed Insights on 3 pages | Remove heavy apps, optimize images |
143
+ | Sitemap | yourdomain.com/sitemap.xml | Should exist and include products + collections |
144
+ | robots.txt | yourdomain.com/robots.txt | Should not block /products/ or /collections/ |
145
+ | 404 errors | Google Search Console > Coverage | 301 redirect old URLs |
146
+
147
+ ---
148
+
149
+ ## Common Shopify SEO Mistakes
150
+
151
+ **Mistake: Disabling the Shopify sitemap**
152
+ The auto-generated sitemap at `/sitemap.xml` is good. Don't replace it with a custom one unless you have a specific reason. Many apps do this and break indexation.
153
+
154
+ **Mistake: Using a page builder for all pages**
155
+ Page builders like PageFly output custom HTML structures that often miss semantic tags (H1, structured data, canonical). Check that builder-created pages still have proper SEO markup.
156
+
157
+ **Mistake: Changing product handles**
158
+ `/products/old-handle` → `/products/new-handle` without a redirect = 404 = lost rankings.
159
+ Shopify doesn't auto-redirect when you change a handle. Add a URL redirect in admin: Settings → Policies → URL Redirects.
160
+
161
+ **Mistake: Publishing all variants as separate products**
162
+ One product with 5 color variants is better than 5 separate products. Consolidates link equity, avoids duplicate content.
163
+
164
+ **Mistake: Keeping "/a/collections/" filtering in index**
165
+ Some filter apps create `/collections/shirts?filter.p.product_type=Formal` URLs. These should be noindexed or disallowed.