@ucptools/validator 1.0.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.
- package/CLAUDE.md +109 -0
- package/CONTRIBUTING.md +113 -0
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/api/analyze-feed.js +140 -0
- package/api/badge.js +185 -0
- package/api/benchmark.js +177 -0
- package/api/directory-stats.ts +29 -0
- package/api/directory.ts +73 -0
- package/api/generate-compliance.js +143 -0
- package/api/generate-schema.js +457 -0
- package/api/generate.js +132 -0
- package/api/security-scan.js +133 -0
- package/api/simulate.js +187 -0
- package/api/tsconfig.json +10 -0
- package/api/validate.js +1351 -0
- package/apify-actor/.actor/actor.json +68 -0
- package/apify-actor/.actor/input_schema.json +32 -0
- package/apify-actor/APIFY-STORE-LISTING.md +412 -0
- package/apify-actor/Dockerfile +8 -0
- package/apify-actor/README.md +166 -0
- package/apify-actor/main.ts +111 -0
- package/apify-actor/package.json +17 -0
- package/apify-actor/src/main.js +199 -0
- package/docs/BRAND-IDENTITY.md +238 -0
- package/docs/BRAND-STYLE-GUIDE.md +356 -0
- package/drizzle/0000_black_king_cobra.sql +39 -0
- package/drizzle/meta/0000_snapshot.json +309 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +10 -0
- package/examples/full-profile.json +70 -0
- package/examples/minimal-profile.json +23 -0
- package/package.json +69 -0
- package/public/.well-known/ucp +25 -0
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/brand.css +321 -0
- package/public/directory.html +701 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/guides/bigcommerce.html +743 -0
- package/public/guides/fastucp.html +838 -0
- package/public/guides/magento.html +779 -0
- package/public/guides/shopify.html +726 -0
- package/public/guides/squarespace.html +749 -0
- package/public/guides/wix.html +747 -0
- package/public/guides/woocommerce.html +733 -0
- package/public/index.html +3835 -0
- package/public/learn.html +396 -0
- package/public/logo.jpeg +0 -0
- package/public/og-image-icon.png +0 -0
- package/public/og-image.png +0 -0
- package/public/robots.txt +6 -0
- package/public/site.webmanifest +31 -0
- package/public/sitemap.xml +69 -0
- package/public/social/linkedin-banner-1128x191.png +0 -0
- package/public/social/temp.PNG +0 -0
- package/public/social/x-header-1500x500.png +0 -0
- package/public/verify.html +410 -0
- package/scripts/generate-favicons.js +44 -0
- package/scripts/generate-ico.js +23 -0
- package/scripts/generate-og-image.js +45 -0
- package/scripts/reset-db.ts +77 -0
- package/scripts/seed-db.ts +71 -0
- package/scripts/setup-benchmark-db.js +70 -0
- package/src/api/server.ts +266 -0
- package/src/cli/index.ts +302 -0
- package/src/compliance/compliance-generator.ts +452 -0
- package/src/compliance/index.ts +28 -0
- package/src/compliance/templates.ts +338 -0
- package/src/compliance/types.ts +170 -0
- package/src/db/index.ts +28 -0
- package/src/db/schema.ts +84 -0
- package/src/feed-analyzer/feed-analyzer.ts +726 -0
- package/src/feed-analyzer/index.ts +34 -0
- package/src/feed-analyzer/types.ts +354 -0
- package/src/generator/index.ts +7 -0
- package/src/generator/key-generator.ts +124 -0
- package/src/generator/profile-builder.ts +402 -0
- package/src/hosting/artifacts-generator.ts +679 -0
- package/src/hosting/index.ts +6 -0
- package/src/index.ts +105 -0
- package/src/security/index.ts +15 -0
- package/src/security/security-scanner.ts +604 -0
- package/src/security/types.ts +55 -0
- package/src/services/directory.ts +434 -0
- package/src/simulator/agent-simulator.ts +941 -0
- package/src/simulator/index.ts +7 -0
- package/src/simulator/types.ts +170 -0
- package/src/types/generator.ts +140 -0
- package/src/types/index.ts +7 -0
- package/src/types/ucp-profile.ts +140 -0
- package/src/types/validation.ts +89 -0
- package/src/validator/index.ts +194 -0
- package/src/validator/network-validator.ts +417 -0
- package/src/validator/rules-validator.ts +297 -0
- package/src/validator/sdk-validator.ts +330 -0
- package/src/validator/structural-validator.ts +476 -0
- package/tests/fixtures/non-compliant-profile.json +25 -0
- package/tests/fixtures/official-sample-profile.json +75 -0
- package/tests/integration/benchmark.test.ts +207 -0
- package/tests/integration/database.test.ts +163 -0
- package/tests/integration/directory-api.test.ts +268 -0
- package/tests/integration/simulate-api.test.ts +230 -0
- package/tests/integration/validate-api.test.ts +269 -0
- package/tests/setup.ts +15 -0
- package/tests/unit/agent-simulator.test.ts +575 -0
- package/tests/unit/compliance-generator.test.ts +374 -0
- package/tests/unit/directory-service.test.ts +272 -0
- package/tests/unit/feed-analyzer.test.ts +517 -0
- package/tests/unit/lint-suggestions.test.ts +423 -0
- package/tests/unit/official-samples.test.ts +211 -0
- package/tests/unit/pdf-report.test.ts +390 -0
- package/tests/unit/sdk-validator.test.ts +531 -0
- package/tests/unit/security-scanner.test.ts +410 -0
- package/tests/unit/validation.test.ts +390 -0
- package/tsconfig.json +20 -0
- package/vercel.json +34 -0
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,779 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<!-- Google Analytics -->
|
|
6
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-J5JSHV7H1E"></script>
|
|
7
|
+
<script>
|
|
8
|
+
window.dataLayer = window.dataLayer || [];
|
|
9
|
+
function gtag() { dataLayer.push(arguments); }
|
|
10
|
+
gtag('js', new Date());
|
|
11
|
+
gtag('config', 'G-J5JSHV7H1E');
|
|
12
|
+
</script>
|
|
13
|
+
<meta charset="UTF-8">
|
|
14
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
15
|
+
<title>Magento UCP Implementation Guide - AI Commerce Ready | UCP Tools</title>
|
|
16
|
+
<meta name="description"
|
|
17
|
+
content="Step-by-step guide to implementing UCP (Universal Commerce Protocol) on Magento / Adobe Commerce. Make your enterprise store AI-ready for ChatGPT and AI shopping agents.">
|
|
18
|
+
<link rel="canonical" href="https://ucptools.dev/guides/magento">
|
|
19
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
20
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
|
21
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
|
22
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
|
23
|
+
<link rel="manifest" href="/site.webmanifest">
|
|
24
|
+
<meta name="theme-color" content="#F26322">
|
|
25
|
+
<meta property="og:title" content="Magento UCP Implementation Guide - AI Commerce Ready">
|
|
26
|
+
<meta property="og:description"
|
|
27
|
+
content="Make your Magento / Adobe Commerce store AI-ready with UCP. Enterprise implementation guide.">
|
|
28
|
+
<meta property="og:image" content="/og-image.png">
|
|
29
|
+
<meta property="og:type" content="article">
|
|
30
|
+
|
|
31
|
+
<!-- Google Fonts -->
|
|
32
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
33
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
34
|
+
<link
|
|
35
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code:wght@400;500&display=swap"
|
|
36
|
+
rel="stylesheet">
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
:root {
|
|
40
|
+
--brand-blue: #2E86AB;
|
|
41
|
+
--brand-teal: #36B5A2;
|
|
42
|
+
--brand-green: #47C97A;
|
|
43
|
+
--brand-gradient: linear-gradient(135deg, #2E86AB 0%, #36B5A2 50%, #47C97A 100%);
|
|
44
|
+
--platform-color: #F26322;
|
|
45
|
+
--platform-dark: #D64D0F;
|
|
46
|
+
--color-dark: #1A2B3C;
|
|
47
|
+
--color-medium: #5A6978;
|
|
48
|
+
--color-light: #94A3B8;
|
|
49
|
+
--color-border: #E2E8F0;
|
|
50
|
+
--color-background: #F8FAFC;
|
|
51
|
+
--color-card: #FFFFFF;
|
|
52
|
+
--color-success: #47C97A;
|
|
53
|
+
--color-warning: #F59E0B;
|
|
54
|
+
--color-error: #EF4444;
|
|
55
|
+
--color-info: #2E86AB;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
59
|
+
|
|
60
|
+
body {
|
|
61
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
62
|
+
background: var(--color-background);
|
|
63
|
+
color: var(--color-dark);
|
|
64
|
+
line-height: 1.6;
|
|
65
|
+
min-height: 100vh;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
a { color: var(--brand-blue); text-decoration: none; }
|
|
69
|
+
a:hover { text-decoration: underline; }
|
|
70
|
+
|
|
71
|
+
.container { max-width: 1200px; margin: 0 auto; padding: 0 20px; }
|
|
72
|
+
|
|
73
|
+
header {
|
|
74
|
+
background: var(--color-card);
|
|
75
|
+
border-bottom: 1px solid var(--color-border);
|
|
76
|
+
padding: 16px 0;
|
|
77
|
+
position: sticky;
|
|
78
|
+
top: 0;
|
|
79
|
+
z-index: 1000;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.header-inner {
|
|
83
|
+
display: flex;
|
|
84
|
+
justify-content: space-between;
|
|
85
|
+
align-items: center;
|
|
86
|
+
max-width: 1200px;
|
|
87
|
+
margin: 0 auto;
|
|
88
|
+
padding: 0 20px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.logo {
|
|
92
|
+
display: flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
gap: 12px;
|
|
95
|
+
font-size: 24px;
|
|
96
|
+
font-weight: 700;
|
|
97
|
+
text-decoration: none;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.logo:hover { text-decoration: none; }
|
|
101
|
+
.logo-icon { width: 40px; height: 40px; border-radius: 8px; }
|
|
102
|
+
|
|
103
|
+
.logo-text {
|
|
104
|
+
background: var(--brand-gradient);
|
|
105
|
+
-webkit-background-clip: text;
|
|
106
|
+
-webkit-text-fill-color: transparent;
|
|
107
|
+
background-clip: text;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.logo-suffix { font-weight: 400; -webkit-text-fill-color: var(--color-medium); }
|
|
111
|
+
|
|
112
|
+
nav { display: flex; gap: 8px; }
|
|
113
|
+
|
|
114
|
+
nav a {
|
|
115
|
+
padding: 8px 16px;
|
|
116
|
+
color: var(--color-medium);
|
|
117
|
+
text-decoration: none;
|
|
118
|
+
font-weight: 500;
|
|
119
|
+
border-radius: 6px;
|
|
120
|
+
transition: all 0.2s;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
nav a:hover {
|
|
124
|
+
color: var(--brand-blue);
|
|
125
|
+
background: rgba(46, 134, 171, 0.08);
|
|
126
|
+
text-decoration: none;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
nav a.active {
|
|
130
|
+
color: var(--brand-blue);
|
|
131
|
+
background: rgba(46, 134, 171, 0.12);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.guide-hero {
|
|
135
|
+
background: linear-gradient(135deg, #D64D0F 0%, #F26322 100%);
|
|
136
|
+
color: white;
|
|
137
|
+
padding: 80px 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.guide-hero .container { max-width: 800px; }
|
|
141
|
+
|
|
142
|
+
.guide-hero h1 {
|
|
143
|
+
font-size: 2.75rem;
|
|
144
|
+
font-weight: 700;
|
|
145
|
+
margin-bottom: 16px;
|
|
146
|
+
line-height: 1.2;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.guide-hero p {
|
|
150
|
+
font-size: 1.25rem;
|
|
151
|
+
opacity: 0.9;
|
|
152
|
+
line-height: 1.6;
|
|
153
|
+
margin-bottom: 24px;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.guide-badges { display: flex; gap: 12px; flex-wrap: wrap; }
|
|
157
|
+
|
|
158
|
+
.guide-badge {
|
|
159
|
+
background: rgba(255, 255, 255, 0.15);
|
|
160
|
+
backdrop-filter: blur(10px);
|
|
161
|
+
padding: 8px 16px;
|
|
162
|
+
border-radius: 24px;
|
|
163
|
+
font-size: 0.9rem;
|
|
164
|
+
font-weight: 500;
|
|
165
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.guide-content {
|
|
169
|
+
display: grid;
|
|
170
|
+
grid-template-columns: 1fr 260px;
|
|
171
|
+
gap: 60px;
|
|
172
|
+
max-width: 1100px;
|
|
173
|
+
margin: 0 auto;
|
|
174
|
+
padding: 60px 20px;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@media (max-width: 968px) {
|
|
178
|
+
.guide-content { grid-template-columns: 1fr; gap: 40px; }
|
|
179
|
+
.guide-sidebar { order: -1; }
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@media (max-width: 600px) {
|
|
183
|
+
.guide-hero h1 { font-size: 2rem; }
|
|
184
|
+
.guide-hero p { font-size: 1.1rem; }
|
|
185
|
+
.header-inner { flex-direction: column; gap: 16px; }
|
|
186
|
+
nav { flex-wrap: wrap; justify-content: center; }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.guide-main section { margin-bottom: 48px; }
|
|
190
|
+
|
|
191
|
+
.guide-main h2 {
|
|
192
|
+
color: var(--color-dark);
|
|
193
|
+
font-size: 1.75rem;
|
|
194
|
+
font-weight: 700;
|
|
195
|
+
margin-bottom: 20px;
|
|
196
|
+
padding-bottom: 12px;
|
|
197
|
+
border-bottom: 2px solid var(--color-border);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.guide-main h3 {
|
|
201
|
+
font-size: 1.25rem;
|
|
202
|
+
font-weight: 600;
|
|
203
|
+
margin: 32px 0 16px;
|
|
204
|
+
color: var(--color-dark);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.guide-main p {
|
|
208
|
+
margin-bottom: 16px;
|
|
209
|
+
color: var(--color-medium);
|
|
210
|
+
font-size: 1.05rem;
|
|
211
|
+
line-height: 1.7;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.guide-main ul, .guide-main ol { margin-bottom: 20px; padding-left: 24px; }
|
|
215
|
+
|
|
216
|
+
.guide-main li {
|
|
217
|
+
margin-bottom: 10px;
|
|
218
|
+
color: var(--color-medium);
|
|
219
|
+
line-height: 1.6;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.guide-main li strong { color: var(--color-dark); }
|
|
223
|
+
|
|
224
|
+
pre {
|
|
225
|
+
background: #1e1e1e;
|
|
226
|
+
color: #d4d4d4;
|
|
227
|
+
padding: 24px;
|
|
228
|
+
border-radius: 12px;
|
|
229
|
+
overflow-x: auto;
|
|
230
|
+
margin: 20px 0;
|
|
231
|
+
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
|
|
232
|
+
font-size: 0.9rem;
|
|
233
|
+
line-height: 1.6;
|
|
234
|
+
border: 1px solid #333;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
code { font-family: 'Fira Code', 'Monaco', 'Consolas', monospace; }
|
|
238
|
+
|
|
239
|
+
:not(pre)>code {
|
|
240
|
+
background: #EEF2F6;
|
|
241
|
+
padding: 3px 8px;
|
|
242
|
+
border-radius: 6px;
|
|
243
|
+
font-size: 0.9em;
|
|
244
|
+
color: var(--platform-dark);
|
|
245
|
+
font-weight: 500;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.step-number {
|
|
249
|
+
display: inline-flex;
|
|
250
|
+
align-items: center;
|
|
251
|
+
justify-content: center;
|
|
252
|
+
width: 32px;
|
|
253
|
+
height: 32px;
|
|
254
|
+
background: var(--platform-color);
|
|
255
|
+
color: white;
|
|
256
|
+
border-radius: 50%;
|
|
257
|
+
font-weight: 700;
|
|
258
|
+
font-size: 0.9rem;
|
|
259
|
+
margin-right: 12px;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.step-title {
|
|
263
|
+
display: flex;
|
|
264
|
+
align-items: center;
|
|
265
|
+
font-size: 1.25rem;
|
|
266
|
+
font-weight: 600;
|
|
267
|
+
margin: 32px 0 16px;
|
|
268
|
+
color: var(--color-dark);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.tip-box {
|
|
272
|
+
background: #EFF6FF;
|
|
273
|
+
border-left: 4px solid var(--brand-blue);
|
|
274
|
+
padding: 20px 24px;
|
|
275
|
+
border-radius: 0 12px 12px 0;
|
|
276
|
+
margin: 24px 0;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.tip-box.warning { background: #FEF3C7; border-color: var(--color-warning); }
|
|
280
|
+
.tip-box.success { background: #DCFCE7; border-color: var(--color-success); }
|
|
281
|
+
.tip-box.platform { background: #FEF4EE; border-color: var(--platform-color); }
|
|
282
|
+
|
|
283
|
+
.tip-box strong {
|
|
284
|
+
display: block;
|
|
285
|
+
margin-bottom: 6px;
|
|
286
|
+
color: var(--color-dark);
|
|
287
|
+
font-size: 1rem;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.tip-box p, .tip-box { color: var(--color-medium); font-size: 0.95rem; }
|
|
291
|
+
|
|
292
|
+
.cta-box {
|
|
293
|
+
background: var(--brand-gradient);
|
|
294
|
+
color: white;
|
|
295
|
+
padding: 40px;
|
|
296
|
+
border-radius: 16px;
|
|
297
|
+
text-align: center;
|
|
298
|
+
margin: 32px 0;
|
|
299
|
+
box-shadow: 0 8px 32px rgba(46, 134, 171, 0.25);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.cta-box h3 { color: white; font-size: 1.5rem; margin-bottom: 12px; }
|
|
303
|
+
.cta-box p { color: rgba(255, 255, 255, 0.9); margin-bottom: 24px; font-size: 1.05rem; }
|
|
304
|
+
|
|
305
|
+
.cta-box .btn {
|
|
306
|
+
background: white;
|
|
307
|
+
color: var(--brand-blue);
|
|
308
|
+
padding: 14px 32px;
|
|
309
|
+
border-radius: 8px;
|
|
310
|
+
text-decoration: none;
|
|
311
|
+
font-weight: 600;
|
|
312
|
+
font-size: 1rem;
|
|
313
|
+
display: inline-block;
|
|
314
|
+
transition: all 0.2s;
|
|
315
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.cta-box .btn:hover {
|
|
319
|
+
transform: translateY(-2px);
|
|
320
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
|
|
321
|
+
text-decoration: none;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
table {
|
|
325
|
+
width: 100%;
|
|
326
|
+
border-collapse: collapse;
|
|
327
|
+
margin: 20px 0;
|
|
328
|
+
background: var(--color-card);
|
|
329
|
+
border-radius: 12px;
|
|
330
|
+
overflow: hidden;
|
|
331
|
+
border: 1px solid var(--color-border);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
th, td {
|
|
335
|
+
text-align: left;
|
|
336
|
+
padding: 16px 20px;
|
|
337
|
+
border-bottom: 1px solid var(--color-border);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
th { background: var(--color-background); font-weight: 600; color: var(--color-dark); }
|
|
341
|
+
tr:last-child td { border-bottom: none; }
|
|
342
|
+
td code { background: #EEF2F6; padding: 4px 8px; border-radius: 4px; }
|
|
343
|
+
|
|
344
|
+
.guide-sidebar { position: sticky; top: 100px; align-self: start; }
|
|
345
|
+
|
|
346
|
+
.sidebar-toc {
|
|
347
|
+
background: var(--color-card);
|
|
348
|
+
border: 1px solid var(--color-border);
|
|
349
|
+
border-radius: 12px;
|
|
350
|
+
padding: 24px;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.sidebar-toc h4 {
|
|
354
|
+
font-size: 0.8rem;
|
|
355
|
+
text-transform: uppercase;
|
|
356
|
+
letter-spacing: 1px;
|
|
357
|
+
color: var(--color-light);
|
|
358
|
+
margin-bottom: 16px;
|
|
359
|
+
font-weight: 600;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.sidebar-toc ul { list-style: none; padding: 0; margin: 0; }
|
|
363
|
+
.sidebar-toc li { margin-bottom: 0; }
|
|
364
|
+
|
|
365
|
+
.sidebar-toc a {
|
|
366
|
+
display: block;
|
|
367
|
+
padding: 10px 12px;
|
|
368
|
+
color: var(--color-medium);
|
|
369
|
+
text-decoration: none;
|
|
370
|
+
font-size: 0.9rem;
|
|
371
|
+
border-radius: 6px;
|
|
372
|
+
transition: all 0.2s;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.sidebar-toc a:hover {
|
|
376
|
+
color: var(--platform-color);
|
|
377
|
+
background: rgba(242, 99, 34, 0.08);
|
|
378
|
+
text-decoration: none;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.other-guides {
|
|
382
|
+
margin-top: 24px;
|
|
383
|
+
padding-top: 24px;
|
|
384
|
+
border-top: 1px solid var(--color-border);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.other-guides h4 {
|
|
388
|
+
font-size: 0.8rem;
|
|
389
|
+
text-transform: uppercase;
|
|
390
|
+
letter-spacing: 1px;
|
|
391
|
+
color: var(--color-light);
|
|
392
|
+
margin-bottom: 12px;
|
|
393
|
+
font-weight: 600;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.other-guides a {
|
|
397
|
+
display: block;
|
|
398
|
+
padding: 8px 12px;
|
|
399
|
+
color: var(--color-medium);
|
|
400
|
+
font-size: 0.85rem;
|
|
401
|
+
border-radius: 6px;
|
|
402
|
+
transition: all 0.2s;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.other-guides a:hover {
|
|
406
|
+
color: var(--brand-blue);
|
|
407
|
+
background: rgba(46, 134, 171, 0.08);
|
|
408
|
+
text-decoration: none;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
footer {
|
|
412
|
+
background: var(--color-dark);
|
|
413
|
+
color: white;
|
|
414
|
+
padding: 48px 0;
|
|
415
|
+
margin-top: 60px;
|
|
416
|
+
text-align: center;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
footer p { margin: 0; opacity: 0.9; }
|
|
420
|
+
footer a { color: var(--brand-teal); }
|
|
421
|
+
footer a:hover { color: var(--brand-green); }
|
|
422
|
+
.footer-links { margin-top: 12px; opacity: 0.7; }
|
|
423
|
+
</style>
|
|
424
|
+
</head>
|
|
425
|
+
|
|
426
|
+
<body>
|
|
427
|
+
<header>
|
|
428
|
+
<div class="header-inner">
|
|
429
|
+
<a href="/" class="logo">
|
|
430
|
+
<img src="/logo.jpeg" alt="UCP.tools logo" class="logo-icon">
|
|
431
|
+
<span class="logo-text">UCP<span class="logo-suffix">.tools</span></span>
|
|
432
|
+
</a>
|
|
433
|
+
<nav>
|
|
434
|
+
<a href="/">Validator</a>
|
|
435
|
+
<a href="/learn">Learn</a>
|
|
436
|
+
<a href="/directory">Directory</a>
|
|
437
|
+
<a href="/guides/magento" class="active">Magento</a>
|
|
438
|
+
</nav>
|
|
439
|
+
</div>
|
|
440
|
+
</header>
|
|
441
|
+
|
|
442
|
+
<div class="guide-hero">
|
|
443
|
+
<div class="container">
|
|
444
|
+
<h1>๐ข Magento / Adobe Commerce UCP Guide</h1>
|
|
445
|
+
<p>Implement UCP on your enterprise Magento or Adobe Commerce store. Enable AI agents to discover and transact with your catalog.</p>
|
|
446
|
+
<div class="guide-badges">
|
|
447
|
+
<span class="guide-badge">๐ค AI Agent Ready</span>
|
|
448
|
+
<span class="guide-badge">๐ข Enterprise Grade</span>
|
|
449
|
+
<span class="guide-badge">๐ง Module Available</span>
|
|
450
|
+
<span class="guide-badge">๐ GraphQL Support</span>
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
</div>
|
|
454
|
+
|
|
455
|
+
<div class="guide-content">
|
|
456
|
+
<main class="guide-main">
|
|
457
|
+
<section id="overview">
|
|
458
|
+
<h2>Why Add UCP to Magento?</h2>
|
|
459
|
+
<p>
|
|
460
|
+
Magento (Adobe Commerce) powers some of the world's largest online stores. Adding UCP support positions your enterprise for AI-driven commerce, allowing AI agents to discover products, check inventory, and complete transactions.
|
|
461
|
+
</p>
|
|
462
|
+
<ul>
|
|
463
|
+
<li><strong>Enterprise Scale:</strong> UCP works with Magento's multi-store, multi-language setup</li>
|
|
464
|
+
<li><strong>GraphQL Ready:</strong> Magento's GraphQL API integrates seamlessly with UCP</li>
|
|
465
|
+
<li><strong>B2B Support:</strong> Expose B2B catalogs and pricing to AI agents</li>
|
|
466
|
+
<li><strong>Headless Compatible:</strong> Works with PWA Studio and headless setups</li>
|
|
467
|
+
</ul>
|
|
468
|
+
|
|
469
|
+
<div class="tip-box platform">
|
|
470
|
+
<strong>๐ข Adobe Commerce Cloud</strong>
|
|
471
|
+
This guide works for both Magento Open Source and Adobe Commerce Cloud. Cloud users should deploy via the standard module deployment process.
|
|
472
|
+
</div>
|
|
473
|
+
</section>
|
|
474
|
+
|
|
475
|
+
<section id="prerequisites">
|
|
476
|
+
<h2>Prerequisites</h2>
|
|
477
|
+
<ul>
|
|
478
|
+
<li>Magento 2.4+ or Adobe Commerce</li>
|
|
479
|
+
<li>SSH/CLI access to your Magento installation</li>
|
|
480
|
+
<li>Composer installed</li>
|
|
481
|
+
<li>Basic understanding of Magento module structure</li>
|
|
482
|
+
</ul>
|
|
483
|
+
</section>
|
|
484
|
+
|
|
485
|
+
<section id="implementation">
|
|
486
|
+
<h2>Implementation</h2>
|
|
487
|
+
|
|
488
|
+
<div class="step-title"><span class="step-number">1</span>Generate Your UCP Profile</div>
|
|
489
|
+
|
|
490
|
+
<div class="cta-box">
|
|
491
|
+
<h3>Generate Your UCP Profile</h3>
|
|
492
|
+
<p>Create a customized UCP profile for your Magento store.</p>
|
|
493
|
+
<a href="/#generate" class="btn">Open Generator โ</a>
|
|
494
|
+
</div>
|
|
495
|
+
|
|
496
|
+
<div class="step-title"><span class="step-number">2</span>Create the Module Structure</div>
|
|
497
|
+
<p>Create a new module to serve the UCP profile:</p>
|
|
498
|
+
|
|
499
|
+
<pre><span style="color:#6A9955"># Create module directories</span>
|
|
500
|
+
mkdir -p app/code/Vendor/Ucp/Controller/WellKnown
|
|
501
|
+
mkdir -p app/code/Vendor/Ucp/etc</pre>
|
|
502
|
+
|
|
503
|
+
<div class="step-title"><span class="step-number">3</span>Create Module Registration</div>
|
|
504
|
+
<p>Create <code>app/code/Vendor/Ucp/registration.php</code>:</p>
|
|
505
|
+
|
|
506
|
+
<pre><span style="color:#C586C0"><?php</span>
|
|
507
|
+
<span style="color:#C586C0">use</span> Magento\Framework\Component\ComponentRegistrar;
|
|
508
|
+
|
|
509
|
+
ComponentRegistrar::register(
|
|
510
|
+
ComponentRegistrar::MODULE,
|
|
511
|
+
<span style="color:#CE9178">'Vendor_Ucp'</span>,
|
|
512
|
+
__DIR__
|
|
513
|
+
);</pre>
|
|
514
|
+
|
|
515
|
+
<div class="step-title"><span class="step-number">4</span>Create module.xml</div>
|
|
516
|
+
<p>Create <code>app/code/Vendor/Ucp/etc/module.xml</code>:</p>
|
|
517
|
+
|
|
518
|
+
<pre><span style="color:#808080"><?xml version="1.0"?></span>
|
|
519
|
+
<span style="color:#569CD6"><config</span> <span style="color:#9CDCFE">xmlns:xsi</span>=<span style="color:#CE9178">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
|
520
|
+
<span style="color:#9CDCFE">xsi:noNamespaceSchemaLocation</span>=<span style="color:#CE9178">"urn:magento:framework:Module/etc/module.xsd"</span><span style="color:#569CD6">></span>
|
|
521
|
+
<span style="color:#569CD6"><module</span> <span style="color:#9CDCFE">name</span>=<span style="color:#CE9178">"Vendor_Ucp"</span> <span style="color:#9CDCFE">setup_version</span>=<span style="color:#CE9178">"1.0.0"</span><span style="color:#569CD6">></span>
|
|
522
|
+
<span style="color:#569CD6"><sequence></span>
|
|
523
|
+
<span style="color:#569CD6"><module</span> <span style="color:#9CDCFE">name</span>=<span style="color:#CE9178">"Magento_Store"</span><span style="color:#569CD6">/></span>
|
|
524
|
+
<span style="color:#569CD6"></sequence></span>
|
|
525
|
+
<span style="color:#569CD6"></module></span>
|
|
526
|
+
<span style="color:#569CD6"></config></span></pre>
|
|
527
|
+
|
|
528
|
+
<div class="step-title"><span class="step-number">5</span>Create Routes Configuration</div>
|
|
529
|
+
<p>Create <code>app/code/Vendor/Ucp/etc/frontend/routes.xml</code>:</p>
|
|
530
|
+
|
|
531
|
+
<pre><span style="color:#808080"><?xml version="1.0"?></span>
|
|
532
|
+
<span style="color:#569CD6"><config</span> <span style="color:#9CDCFE">xmlns:xsi</span>=<span style="color:#CE9178">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
|
533
|
+
<span style="color:#9CDCFE">xsi:noNamespaceSchemaLocation</span>=<span style="color:#CE9178">"urn:magento:framework:App/etc/routes.xsd"</span><span style="color:#569CD6">></span>
|
|
534
|
+
<span style="color:#569CD6"><router</span> <span style="color:#9CDCFE">id</span>=<span style="color:#CE9178">"standard"</span><span style="color:#569CD6">></span>
|
|
535
|
+
<span style="color:#569CD6"><route</span> <span style="color:#9CDCFE">id</span>=<span style="color:#CE9178">"wellknown"</span> <span style="color:#9CDCFE">frontName</span>=<span style="color:#CE9178">".well-known"</span><span style="color:#569CD6">></span>
|
|
536
|
+
<span style="color:#569CD6"><module</span> <span style="color:#9CDCFE">name</span>=<span style="color:#CE9178">"Vendor_Ucp"</span><span style="color:#569CD6">/></span>
|
|
537
|
+
<span style="color:#569CD6"></route></span>
|
|
538
|
+
<span style="color:#569CD6"></router></span>
|
|
539
|
+
<span style="color:#569CD6"></config></span></pre>
|
|
540
|
+
|
|
541
|
+
<div class="step-title"><span class="step-number">6</span>Create the Controller</div>
|
|
542
|
+
<p>Create <code>app/code/Vendor/Ucp/Controller/WellKnown/Ucp.php</code>:</p>
|
|
543
|
+
|
|
544
|
+
<pre><span style="color:#C586C0"><?php</span>
|
|
545
|
+
<span style="color:#C586C0">namespace</span> Vendor\Ucp\Controller\WellKnown;
|
|
546
|
+
|
|
547
|
+
<span style="color:#C586C0">use</span> Magento\Framework\App\Action\HttpGetActionInterface;
|
|
548
|
+
<span style="color:#C586C0">use</span> Magento\Framework\Controller\Result\JsonFactory;
|
|
549
|
+
<span style="color:#C586C0">use</span> Magento\Store\Model\StoreManagerInterface;
|
|
550
|
+
<span style="color:#C586C0">use</span> Magento\Framework\App\Config\ScopeConfigInterface;
|
|
551
|
+
|
|
552
|
+
<span style="color:#C586C0">class</span> <span style="color:#4EC9B0">Ucp</span> <span style="color:#C586C0">implements</span> HttpGetActionInterface
|
|
553
|
+
{
|
|
554
|
+
<span style="color:#C586C0">private</span> JsonFactory $jsonFactory;
|
|
555
|
+
<span style="color:#C586C0">private</span> StoreManagerInterface $storeManager;
|
|
556
|
+
<span style="color:#C586C0">private</span> ScopeConfigInterface $scopeConfig;
|
|
557
|
+
|
|
558
|
+
<span style="color:#C586C0">public function</span> <span style="color:#DCDCAA">__construct</span>(
|
|
559
|
+
JsonFactory $jsonFactory,
|
|
560
|
+
StoreManagerInterface $storeManager,
|
|
561
|
+
ScopeConfigInterface $scopeConfig
|
|
562
|
+
) {
|
|
563
|
+
$this->jsonFactory = $jsonFactory;
|
|
564
|
+
$this->storeManager = $storeManager;
|
|
565
|
+
$this->scopeConfig = $scopeConfig;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
<span style="color:#C586C0">public function</span> <span style="color:#DCDCAA">execute</span>()
|
|
569
|
+
{
|
|
570
|
+
$store = $this->storeManager->getStore();
|
|
571
|
+
$baseUrl = $store->getBaseUrl();
|
|
572
|
+
|
|
573
|
+
$profile = [
|
|
574
|
+
<span style="color:#CE9178">'profile_version'</span> => <span style="color:#CE9178">'1.0'</span>,
|
|
575
|
+
<span style="color:#CE9178">'merchant'</span> => [
|
|
576
|
+
<span style="color:#CE9178">'name'</span> => $this->scopeConfig->getValue(<span style="color:#CE9178">'general/store_information/name'</span>),
|
|
577
|
+
<span style="color:#CE9178">'url'</span> => $baseUrl,
|
|
578
|
+
<span style="color:#CE9178">'contact'</span> => [
|
|
579
|
+
<span style="color:#CE9178">'email'</span> => $this->scopeConfig->getValue(<span style="color:#CE9178">'trans_email/ident_general/email'</span>)
|
|
580
|
+
]
|
|
581
|
+
],
|
|
582
|
+
<span style="color:#CE9178">'capabilities'</span> => [<span style="color:#CE9178">'browse'</span>, <span style="color:#CE9178">'search'</span>],
|
|
583
|
+
<span style="color:#CE9178">'policies'</span> => [
|
|
584
|
+
<span style="color:#CE9178">'returns_url'</span> => $baseUrl . <span style="color:#CE9178">'returns'</span>,
|
|
585
|
+
<span style="color:#CE9178">'shipping_url'</span> => $baseUrl . <span style="color:#CE9178">'shipping-policy'</span>,
|
|
586
|
+
<span style="color:#CE9178">'privacy_url'</span> => $baseUrl . <span style="color:#CE9178">'privacy-policy'</span>
|
|
587
|
+
],
|
|
588
|
+
<span style="color:#CE9178">'service_bindings'</span> => [
|
|
589
|
+
[
|
|
590
|
+
<span style="color:#CE9178">'type'</span> => <span style="color:#CE9178">'REST'</span>,
|
|
591
|
+
<span style="color:#CE9178">'base_url'</span> => $baseUrl . <span style="color:#CE9178">'rest/V1'</span>
|
|
592
|
+
],
|
|
593
|
+
[
|
|
594
|
+
<span style="color:#CE9178">'type'</span> => <span style="color:#CE9178">'GraphQL'</span>,
|
|
595
|
+
<span style="color:#CE9178">'base_url'</span> => $baseUrl . <span style="color:#CE9178">'graphql'</span>
|
|
596
|
+
]
|
|
597
|
+
]
|
|
598
|
+
];
|
|
599
|
+
|
|
600
|
+
$result = $this->jsonFactory->create();
|
|
601
|
+
$result->setHeader(<span style="color:#CE9178">'Access-Control-Allow-Origin'</span>, <span style="color:#CE9178">'*'</span>);
|
|
602
|
+
$result->setData($profile);
|
|
603
|
+
|
|
604
|
+
<span style="color:#C586C0">return</span> $result;
|
|
605
|
+
}
|
|
606
|
+
}</pre>
|
|
607
|
+
|
|
608
|
+
<div class="step-title"><span class="step-number">7</span>Enable the Module</div>
|
|
609
|
+
<pre><span style="color:#6A9955"># Enable the module</span>
|
|
610
|
+
bin/magento module:enable Vendor_Ucp
|
|
611
|
+
|
|
612
|
+
<span style="color:#6A9955"># Run setup upgrade</span>
|
|
613
|
+
bin/magento setup:upgrade
|
|
614
|
+
|
|
615
|
+
<span style="color:#6A9955"># Clear cache</span>
|
|
616
|
+
bin/magento cache:clean</pre>
|
|
617
|
+
|
|
618
|
+
<div class="tip-box warning">
|
|
619
|
+
<strong>โ ๏ธ Production Deployment</strong>
|
|
620
|
+
For Adobe Commerce Cloud, commit the module to your repository and deploy through the standard pipeline.
|
|
621
|
+
</div>
|
|
622
|
+
</section>
|
|
623
|
+
|
|
624
|
+
<section id="graphql">
|
|
625
|
+
<h2>GraphQL Integration</h2>
|
|
626
|
+
<p>
|
|
627
|
+
Magento's GraphQL API is ideal for AI agents. Expose your GraphQL endpoint in the UCP profile for efficient product queries.
|
|
628
|
+
</p>
|
|
629
|
+
|
|
630
|
+
<h3>Sample GraphQL Query for AI Agents</h3>
|
|
631
|
+
<pre>{
|
|
632
|
+
products(search: <span style="color:#CE9178">"laptop"</span>, pageSize: <span style="color:#B5CEA8">10</span>) {
|
|
633
|
+
items {
|
|
634
|
+
name
|
|
635
|
+
sku
|
|
636
|
+
price_range {
|
|
637
|
+
minimum_price {
|
|
638
|
+
final_price {
|
|
639
|
+
value
|
|
640
|
+
currency
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
image {
|
|
645
|
+
url
|
|
646
|
+
}
|
|
647
|
+
stock_status
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}</pre>
|
|
651
|
+
|
|
652
|
+
<div class="tip-box">
|
|
653
|
+
<strong>๐ก Pro Tip</strong>
|
|
654
|
+
Consider creating a dedicated GraphQL schema for AI agents with optimized queries for product discovery.
|
|
655
|
+
</div>
|
|
656
|
+
</section>
|
|
657
|
+
|
|
658
|
+
<section id="multistore">
|
|
659
|
+
<h2>Multi-Store Configuration</h2>
|
|
660
|
+
<p>For multi-store setups, each store view can have its own UCP profile. The module automatically uses the current store context.</p>
|
|
661
|
+
|
|
662
|
+
<table>
|
|
663
|
+
<tr>
|
|
664
|
+
<th>Store View</th>
|
|
665
|
+
<th>UCP Endpoint</th>
|
|
666
|
+
</tr>
|
|
667
|
+
<tr>
|
|
668
|
+
<td>Default</td>
|
|
669
|
+
<td><code>https://store.com/.well-known/ucp</code></td>
|
|
670
|
+
</tr>
|
|
671
|
+
<tr>
|
|
672
|
+
<td>French</td>
|
|
673
|
+
<td><code>https://store.com/fr/.well-known/ucp</code></td>
|
|
674
|
+
</tr>
|
|
675
|
+
<tr>
|
|
676
|
+
<td>German</td>
|
|
677
|
+
<td><code>https://store.com/de/.well-known/ucp</code></td>
|
|
678
|
+
</tr>
|
|
679
|
+
</table>
|
|
680
|
+
</section>
|
|
681
|
+
|
|
682
|
+
<section id="validation">
|
|
683
|
+
<h2>Validate Your Implementation</h2>
|
|
684
|
+
|
|
685
|
+
<div class="cta-box">
|
|
686
|
+
<h3>Validate Your Magento Store</h3>
|
|
687
|
+
<p>Check your UCP implementation and AI commerce readiness.</p>
|
|
688
|
+
<a href="/" class="btn">Run Validation โ</a>
|
|
689
|
+
</div>
|
|
690
|
+
</section>
|
|
691
|
+
|
|
692
|
+
<section id="common-issues">
|
|
693
|
+
<h2>Common Issues & Solutions</h2>
|
|
694
|
+
|
|
695
|
+
<table>
|
|
696
|
+
<tr>
|
|
697
|
+
<th>Issue</th>
|
|
698
|
+
<th>Solution</th>
|
|
699
|
+
</tr>
|
|
700
|
+
<tr>
|
|
701
|
+
<td>404 on <code>/.well-known/ucp</code></td>
|
|
702
|
+
<td>Run <code>bin/magento cache:clean</code> and check routes.xml</td>
|
|
703
|
+
</tr>
|
|
704
|
+
<tr>
|
|
705
|
+
<td>Module not loading</td>
|
|
706
|
+
<td>Run <code>bin/magento setup:upgrade</code></td>
|
|
707
|
+
</tr>
|
|
708
|
+
<tr>
|
|
709
|
+
<td>Empty store name</td>
|
|
710
|
+
<td>Configure store name in Stores โ Configuration โ General</td>
|
|
711
|
+
</tr>
|
|
712
|
+
<tr>
|
|
713
|
+
<td>Varnish caching issues</td>
|
|
714
|
+
<td>Add <code>/.well-known/ucp</code> to cache bypass rules</td>
|
|
715
|
+
</tr>
|
|
716
|
+
</table>
|
|
717
|
+
</section>
|
|
718
|
+
|
|
719
|
+
<section id="testing">
|
|
720
|
+
<h2>๐ค Test with AI Agents</h2>
|
|
721
|
+
|
|
722
|
+
<div class="cta-box">
|
|
723
|
+
<h3>Run AI Agent Simulation</h3>
|
|
724
|
+
<p>Test how AI shopping agents will interact with your Magento store.</p>
|
|
725
|
+
<a href="/#simulate" class="btn">Open Simulator โ</a>
|
|
726
|
+
</div>
|
|
727
|
+
</section>
|
|
728
|
+
|
|
729
|
+
<section id="resources">
|
|
730
|
+
<h2>Resources</h2>
|
|
731
|
+
<ul>
|
|
732
|
+
<li><a href="https://ucp.dev" target="_blank">Official UCP Specification</a></li>
|
|
733
|
+
<li><a href="https://developer.adobe.com/commerce/webapi/graphql/" target="_blank">Magento GraphQL Developer Guide</a></li>
|
|
734
|
+
<li><a href="https://developer.adobe.com/commerce/php/development/" target="_blank">Magento PHP Developer Guide</a></li>
|
|
735
|
+
<li><a href="/learn">UCP Learning Center</a></li>
|
|
736
|
+
</ul>
|
|
737
|
+
</section>
|
|
738
|
+
</main>
|
|
739
|
+
|
|
740
|
+
<aside class="guide-sidebar">
|
|
741
|
+
<div class="sidebar-toc">
|
|
742
|
+
<h4>On This Page</h4>
|
|
743
|
+
<ul>
|
|
744
|
+
<li><a href="#overview">Why Add UCP?</a></li>
|
|
745
|
+
<li><a href="#prerequisites">Prerequisites</a></li>
|
|
746
|
+
<li><a href="#implementation">Implementation</a></li>
|
|
747
|
+
<li><a href="#graphql">GraphQL Integration</a></li>
|
|
748
|
+
<li><a href="#multistore">Multi-Store Setup</a></li>
|
|
749
|
+
<li><a href="#validation">Validation</a></li>
|
|
750
|
+
<li><a href="#common-issues">Common Issues</a></li>
|
|
751
|
+
<li><a href="#testing">Test with AI</a></li>
|
|
752
|
+
<li><a href="#resources">Resources</a></li>
|
|
753
|
+
</ul>
|
|
754
|
+
</div>
|
|
755
|
+
|
|
756
|
+
<div class="other-guides">
|
|
757
|
+
<h4>Other Platforms</h4>
|
|
758
|
+
<a href="/guides/shopify">Shopify</a>
|
|
759
|
+
<a href="/guides/woocommerce">WooCommerce</a>
|
|
760
|
+
<a href="/guides/wix">Wix</a>
|
|
761
|
+
<a href="/guides/bigcommerce">BigCommerce</a>
|
|
762
|
+
<a href="/guides/squarespace">Squarespace</a>
|
|
763
|
+
</div>
|
|
764
|
+
</aside>
|
|
765
|
+
</div>
|
|
766
|
+
|
|
767
|
+
<footer>
|
|
768
|
+
<div class="container">
|
|
769
|
+
<p>UCP Tools โ Built for the AI Commerce era</p>
|
|
770
|
+
<p class="footer-links">
|
|
771
|
+
<a href="https://github.com/Nolpak14/ucp-tools" target="_blank">GitHub</a> ยท
|
|
772
|
+
<a href="https://ucp.dev" target="_blank">UCP Spec</a> ยท
|
|
773
|
+
<a href="/">Validator</a>
|
|
774
|
+
</p>
|
|
775
|
+
</div>
|
|
776
|
+
</footer>
|
|
777
|
+
</body>
|
|
778
|
+
|
|
779
|
+
</html>
|