@hostinger/mcp 3.3.0 → 3.3.1
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/CHANGELOG.md +7 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/headless/SKILL.md +68 -70
- package/skills/headless/connect/SKILL.md +1 -6
- package/skills/headless/steps/01-check-state/SKILL.md +24 -8
- package/skills/headless/steps/02-refine/SKILL.md +91 -24
- package/skills/headless/steps/03-provision/SKILL.md +63 -8
- package/skills/headless/steps/03-provision/ecommerce/SKILL.md +11 -2
- package/skills/headless/steps/03-provision/wordpress/SKILL.md +164 -15
- package/skills/headless/steps/04-content-model/SKILL.md +95 -17
- package/skills/headless/steps/04-content-model/wordpress/SKILL.md +66 -21
- package/skills/headless/steps/04-content-model/wordpress/woocommerce.md +153 -0
- package/skills/headless/steps/05-design/SKILL.md +9 -0
- package/skills/headless/steps/06-frontend/SKILL.md +31 -2
- package/skills/headless/steps/07-validate/SKILL.md +4 -1
- package/skills/headless/steps/08-deploy/SKILL.md +11 -3
- package/skills/headless/steps/09-done/SKILL.md +10 -4
- package/src/core/skills.js +49 -42
- package/src/core/skills.ts +49 -42
- package/src/servers/agency-hosting.js +1 -1
- package/src/servers/agency-hosting.ts +1 -1
- package/src/servers/agent-readiness.js +1 -1
- package/src/servers/agent-readiness.ts +1 -1
- package/src/servers/all.js +1 -1
- package/src/servers/all.ts +1 -1
- package/src/servers/billing.js +1 -1
- package/src/servers/billing.ts +1 -1
- package/src/servers/dns.js +1 -1
- package/src/servers/dns.ts +1 -1
- package/src/servers/domains.js +1 -1
- package/src/servers/domains.ts +1 -1
- package/src/servers/ecommerce.js +1 -1
- package/src/servers/ecommerce.ts +1 -1
- package/src/servers/horizons.js +1 -1
- package/src/servers/horizons.ts +1 -1
- package/src/servers/hosting.js +1 -1
- package/src/servers/hosting.ts +1 -1
- package/src/servers/mail.js +1 -1
- package/src/servers/mail.ts +1 -1
- package/src/servers/reach.js +1 -1
- package/src/servers/reach.ts +1 -1
- package/src/servers/vps.js +1 -1
- package/src/servers/vps.ts +1 -1
- package/src/servers/wordpress.js +1 -1
- package/src/servers/wordpress.ts +1 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# headless — WooCommerce cookbook (headless store on WordPress)
|
|
2
|
+
|
|
3
|
+
A companion recipe to `SKILL.md` (WordPress content model). Use it whenever the WordPress backend carries
|
|
4
|
+
a **WooCommerce store** (`site.json → woocommerce.enabled: true`) — a brief whose **Suggested backend** is
|
|
5
|
+
`**WordPress + WooCommerce**` (one site: content **and** commerce).
|
|
6
|
+
|
|
7
|
+
**WooCommerce is not a separate backend.** It is the `woocommerce` plugin on a normal headless WordPress
|
|
8
|
+
install at `/cms` (installed in the provision step). This cookbook is the authoritative home for the store
|
|
9
|
+
data layer: how to **seed and CRUD** products, categories and coupons, and how the **storefront** reads
|
|
10
|
+
the cart, coupons and checkout.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1 — The one rule: drive the store through the per-site WP MCP
|
|
15
|
+
|
|
16
|
+
A **custom plugin cannot be installed into a headless `/cms`** from a coding agent (same limit that
|
|
17
|
+
removed `wp-development.md`). So there is **no seed plugin, no WP-CLI, and no REST consumer key in this
|
|
18
|
+
flow.** Instead, the **per-site WP MCP** (the Hostinger AI Assistant — the same JWT session the WordPress
|
|
19
|
+
content push uses, see `SKILL.md` Step 1) exposes **native WooCommerce abilities**. Seed and manage the
|
|
20
|
+
catalog through them, exactly as posts/pages are created.
|
|
21
|
+
|
|
22
|
+
Relevant abilities (names from `hostinger-ai-discover-abilities`; call `get-ability-info` for each schema
|
|
23
|
+
before use — they mirror the WooCommerce REST v3 shapes):
|
|
24
|
+
|
|
25
|
+
| Area | Abilities |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Products | `wc-products-search` · `wc-products-get` · `wc-products-create` · `wc-products-update` · `wc-products-delete` |
|
|
28
|
+
| Categories / tags / brands | `wc-product-categories-{list,create,update,delete}` · `wc-product-tags-*` · `wc-product-brands-*` |
|
|
29
|
+
| Coupons | `wc-coupons-{search,get,create,update,delete,batch}` |
|
|
30
|
+
| Orders | `wc-orders-{search,get,create,update,delete}` |
|
|
31
|
+
| Reports | `wc-reports-{sales,orders-totals,products-totals,coupons-totals,…}` |
|
|
32
|
+
| Media | `media-upload-from-url` (product images — WordPress keeps its own copy) |
|
|
33
|
+
|
|
34
|
+
All run as the install's admin **inside the MCP session** — no consumer keys, no Basic Auth. This is
|
|
35
|
+
proven: a `wc-products-create` call makes a product that immediately appears on the public Store API.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2 — The storefront reads the public Store API
|
|
40
|
+
|
|
41
|
+
The **frontend** never touches the per-site MCP or any key. It reads the **public WooCommerce Store API**
|
|
42
|
+
at `site.json → urls.store_api` (`/cms/wp-json/wc/store/v1`) — public, open CORS, no auth for reads.
|
|
43
|
+
Pretty permalinks are on by default on a headless install, so the Store API resolves immediately.
|
|
44
|
+
|
|
45
|
+
| Store API call | Use |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `GET /products?per_page=100` · `GET /products/<id>` · `?slug=<slug>` | catalog + product pages |
|
|
48
|
+
| `GET /products/categories` | category nav |
|
|
49
|
+
| `GET /cart` | current cart (seeds the `Cart-Token`) |
|
|
50
|
+
| `POST /cart/add-item` `{ id, quantity }` · `/cart/update-item` `{ key, quantity }` · `/cart/remove-item` `{ key }` | cart mutations |
|
|
51
|
+
| `POST /cart/apply-coupon` `{ code }` · `/cart/remove-coupon` `{ code }` | coupons on the cart |
|
|
52
|
+
| `POST /checkout` `{ billing_address, shipping_address, payment_method }` | place an order |
|
|
53
|
+
|
|
54
|
+
**Store API auth for writes** (cart/checkout): send the **`Nonce`** header (read it from the `Nonce` /
|
|
55
|
+
`X-WC-Store-API-Nonce` response header of a prior Store API GET and echo it back) **and** the
|
|
56
|
+
**`Cart-Token`** header (a JWT the Store API returns on the first cart response — resend it on every
|
|
57
|
+
cart call so a headless client keeps one cart; persist it in `localStorage`). Reads need neither.
|
|
58
|
+
|
|
59
|
+
**Pricing / minor units.** The Store API returns **integer-string** prices in minor units plus the
|
|
60
|
+
divisor: `prices.price` (e.g. `"1999"`) with `prices.currency_minor_unit` (e.g. `2`) and
|
|
61
|
+
`prices.currency_code`. Display value = `Number(price) / 10 ** currency_minor_unit`. **Pagination:**
|
|
62
|
+
`?page=&per_page=` (max 100), with `X-WP-Total` / `X-WP-TotalPages` headers.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3 — Seeding the catalog (content-model push)
|
|
67
|
+
|
|
68
|
+
Run after provision installed + activated WooCommerce (`site.json → woocommerce.enabled: true`), inside
|
|
69
|
+
the authenticated per-site WP MCP session (`SKILL.md` Step 1). Seed from the prepared catalog in
|
|
70
|
+
`content-model.md`. **Idempotent by SKU** (products) and **code** (coupons) — list/search first, create
|
|
71
|
+
only if absent, so a re-run never duplicates.
|
|
72
|
+
|
|
73
|
+
1. **Product categories** — for each category: `wc-product-categories-list` (match by `slug`/`name`,
|
|
74
|
+
reuse the id) else `wc-product-categories-create { name, slug }`. Keep `name → id`.
|
|
75
|
+
2. **Products** — for each product: `wc-products-search { sku: "<sku>" }`; a hit → reuse its id; empty →
|
|
76
|
+
`wc-products-create`:
|
|
77
|
+
```json
|
|
78
|
+
{ "name": "...", "type": "simple", "sku": "<unique>", "regular_price": "39.99",
|
|
79
|
+
"description": "...", "short_description": "...", "status": "publish",
|
|
80
|
+
"categories": [ { "id": <catId> } ] }
|
|
81
|
+
```
|
|
82
|
+
- `regular_price` is a **decimal string in major units** (`"39.99"`) on the ability side — the Store
|
|
83
|
+
API re-exposes it as minor units to the storefront.
|
|
84
|
+
- **Variable products:** create the parent (`type: "variable"`) with its attributes, then the
|
|
85
|
+
variations (via the product update / variations ability that discovery lists).
|
|
86
|
+
3. **Product images** — `media-upload-from-url { url, filename, alt_text, title }` (WordPress downloads
|
|
87
|
+
and stores its own copy; raster, HTTPS, direct file URL — source like the parent `SKILL.md` Unsplash
|
|
88
|
+
flow). Attach the returned media id to the product (`wc-products-update { id, images: [ { id } ] }`).
|
|
89
|
+
Idempotency: skip when the product already has images.
|
|
90
|
+
4. **Coupons** — for each coupon: `wc-coupons-search { code }`; empty → `wc-coupons-create`:
|
|
91
|
+
```json
|
|
92
|
+
{ "code": "WELCOME10", "discount_type": "percent", "amount": "10" }
|
|
93
|
+
```
|
|
94
|
+
(`discount_type`: `percent` | `fixed_cart` | `fixed_product`.)
|
|
95
|
+
|
|
96
|
+
Record the SKU → id map, category ids and coupon codes into `content-model.md` under
|
|
97
|
+
`## Created in WooCommerce` so the frontend and any re-run resolve references directly.
|
|
98
|
+
|
|
99
|
+
**Verify over the public Store API (no auth):**
|
|
100
|
+
- `GET {store_api}/products?per_page=100` → count matches the plan; each has `prices` (minor units +
|
|
101
|
+
`currency_minor_unit`) and, where seeded, an image.
|
|
102
|
+
- `GET {store_api}/products/categories` → every planned category present.
|
|
103
|
+
- Coupon: `wc-coupons-search { code }` returns it, or apply it to a throwaway cart and see the total drop.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 4 — Checkout is owner-completed (the one gate)
|
|
108
|
+
|
|
109
|
+
A fresh WooCommerce install has **no payment gateway and no shipping zone enabled**, and **neither is
|
|
110
|
+
reachable from the headless tooling** — there is no payment/shipping MCP ability, and `wp-settings-update`
|
|
111
|
+
only writes standard WordPress settings (it ignores `woocommerce_*` options). So:
|
|
112
|
+
|
|
113
|
+
- **The catalog, product pages, client-side cart and coupon application all work headlessly.**
|
|
114
|
+
- **Checkout (`POST /checkout`) does not work until the owner enables a payment method + a shipping zone
|
|
115
|
+
in wp-admin** (WooCommerce → Settings → Payments / Shipping; reach it via the one-click login in Step 9).
|
|
116
|
+
Cash on Delivery is the zero-config choice once enabled.
|
|
117
|
+
- Treat this exactly like the Hostinger Ecommerce `payment_enabled: false` gate: record
|
|
118
|
+
`woocommerce.payment_enabled: false`, tell the user in one line that checkout needs that one setup step,
|
|
119
|
+
and **never block the build on it**. The frontend renders a graceful disabled-checkout state and does not
|
|
120
|
+
call `/checkout` while `payment_enabled` is `false`. Flip it to `true` only after the owner confirms a
|
|
121
|
+
gateway is live. **Never ask the user for payment credentials.**
|
|
122
|
+
|
|
123
|
+
Store **currency** and **address** (`woocommerce_*` options) likewise aren't settable headlessly — they
|
|
124
|
+
follow the install default; the owner changes them in wp-admin if needed.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 5 — REST API v3 (optional, owner-only — not used by this flow)
|
|
129
|
+
|
|
130
|
+
WooCommerce also exposes the authenticated **REST API v3** at `site.json → urls.wc_rest_api`
|
|
131
|
+
(`/cms/wp-json/wc/v3`) for external/server-side integrations. **This build never uses it** — seeding goes
|
|
132
|
+
through the per-site MCP and the storefront uses the public Store API. Document it for the owner only:
|
|
133
|
+
|
|
134
|
+
- **Auth:** `Authorization: Basic base64("<consumer_key>:<consumer_secret>")`, **HTTPS only**, server-side
|
|
135
|
+
only — **never ship a key to the browser.**
|
|
136
|
+
- **Keys:** the owner generates a key pair in **wp-admin → WooCommerce → Settings → Advanced → REST API**
|
|
137
|
+
(the agent cannot mint one headlessly). Store it in the owner's own environment, not in `site.json` or
|
|
138
|
+
the repo.
|
|
139
|
+
- **Endpoints** (same shapes as the abilities above): `GET/POST/PUT/DELETE /products`, `/products/<id>/variations`,
|
|
140
|
+
`/products/categories`, `/coupons`, `/orders`. Idempotency via `?sku=` / `?code=`. Pagination via
|
|
141
|
+
`?page=&per_page=` + `X-WP-Total`.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 6 — Idempotency & verification checklist
|
|
146
|
+
|
|
147
|
+
- **Idempotency keys:** products → **SKU** (`wc-products-search { sku }`); coupons → **code**
|
|
148
|
+
(`wc-coupons-search { code }`); categories → **slug/name**; images → skip when the product already has
|
|
149
|
+
`images`.
|
|
150
|
+
- **Verify over the public Store API** (no auth) — products count + prices + categories, and a coupon via
|
|
151
|
+
a cart apply. Record the id/SKU map into `content-model.md`.
|
|
152
|
+
- **Checkout** is verified only when `payment_enabled` is `true`; while `false`, confirming the catalog +
|
|
153
|
+
cart over the Store API is the whole job.
|
|
@@ -13,6 +13,15 @@ not a conversation: the frontend step implements `design.md`, not the chat.
|
|
|
13
13
|
user gave. **Out:** `~/.hostinger/<domain>/design.md` and the logo files in
|
|
14
14
|
`~/.hostinger/<domain>/brand/`.
|
|
15
15
|
|
|
16
|
+
> ## ⚠️ Build mode: "Bring your own frontend"? This step defers to the user
|
|
17
|
+
> Read `brief.md` → **Build mode** first. When it is **Bring your own frontend**, the user drives the
|
|
18
|
+
> design — **do not generate three directions or write a prescriptive `design.md` over their project.**
|
|
19
|
+
> The frontend already exists (or the user vibe-codes it with you); your job is to follow *their*
|
|
20
|
+
> direction, not impose one. Skip Steps 1–7 below: either write nothing, or capture only what the user
|
|
21
|
+
> explicitly asks for (a short note of their stated colours/vibe) so the frontend step has it. The logo
|
|
22
|
+
> and token work here apply only when **Build mode is "Agent designs and builds"**. (This mirrors the
|
|
23
|
+
> frontend step's existing "existing app the user brought" handling, now generalised to any backend.)
|
|
24
|
+
|
|
16
25
|
This is **prepare work**: it runs while provision settles (see *Background provision & the instance
|
|
17
26
|
barrier* in the top-level `SKILL.md`). Nothing here calls the Hostinger connector or the backend.
|
|
18
27
|
|
|
@@ -11,6 +11,18 @@ is where it becomes real code. There's no per-framework recipe — use good judg
|
|
|
11
11
|
as the contract, and ask only for the clarifications you genuinely need. **Out:** source in the site
|
|
12
12
|
workspace `~/.hostinger/<domain>/src/`.
|
|
13
13
|
|
|
14
|
+
> ## ⚠️ Build mode: "Bring your own frontend"? Read this first (any backend)
|
|
15
|
+
> Read `brief.md` → **Build mode**. When it is **Bring your own frontend**, the user already has a
|
|
16
|
+
> frontend (the project in the folder the command was run in) and this step **wires it to the backend
|
|
17
|
+
> from `site.json` — it does not scaffold a new project and there is usually no `design.md` to
|
|
18
|
+
> implement** (the design step deferred to the user). **Use their project as the source**: copy or
|
|
19
|
+
> point `~/.hostinger/<domain>/src/` at it, keep its framework and UI, and collaborate on changes at
|
|
20
|
+
> the user's direction (vibe-code with them). Your job is to connect it to the live backend (WordPress
|
|
21
|
+
> `wp/v2` reads, the WooCommerce/Ecommerce Store API, env/keys) and make it deployable (set
|
|
22
|
+
> `engines.node` to `22`, remove any `.htaccess`), then hand off to deploy. This generalises the Webapp
|
|
23
|
+
> "existing app" case below to WordPress and Ecommerce too. When **Build mode is "Agent designs and
|
|
24
|
+
> builds"**, ignore this box and proceed normally (scaffold + implement `design.md`).
|
|
25
|
+
|
|
14
26
|
> ## ⚠️ Webapp backend? Read this first
|
|
15
27
|
> A `webapp` brief has **no CMS/store and no `content-model.md`** — the app owns its own data (its own
|
|
16
28
|
> API, or the MySQL database recorded in `site.json → database`). It comes in two shapes, decided back in
|
|
@@ -27,7 +39,7 @@ workspace `~/.hostinger/<domain>/src/`.
|
|
|
27
39
|
> there is still **no `content-model.md`** to bind against.
|
|
28
40
|
>
|
|
29
41
|
> Framework choice (Step 1), the build, and hand-off (Step 4) apply to both. The per-backend bullets in
|
|
30
|
-
> Step 3 are **WordPress/Ecommerce only** — for a webapp follow the Webapp bullet there.
|
|
42
|
+
> Step 3 are **WordPress / WooCommerce / Ecommerce only** — for a webapp follow the Webapp bullet there.
|
|
31
43
|
|
|
32
44
|
## Step 1 — Pick the framework (guess → default → confirm)
|
|
33
45
|
|
|
@@ -36,6 +48,7 @@ it, and the backend constraint:
|
|
|
36
48
|
|
|
37
49
|
- **Ecommerce → SSR required** (carts/search need per-request rendering). Any SSR framework works —
|
|
38
50
|
Next.js is the default, not a requirement (Express, Nuxt, SvelteKit, etc. are all fine).
|
|
51
|
+
- **WordPress + WooCommerce → SSR required** (same reason — cart/checkout need per-request rendering).
|
|
39
52
|
- **WordPress → SSG (Astro)** when the brief says SSG, otherwise **SSR (Next.js default)**.
|
|
40
53
|
- **Webapp → the app's own stack.** An **existing app** keeps its current framework (don't impose one); a
|
|
41
54
|
**new app** uses whatever fits the brief (SSR or SPA). Either way it deploys as a Node.js app (Step 8) —
|
|
@@ -87,7 +100,23 @@ Read the backend from `site.json`:
|
|
|
87
100
|
|
|
88
101
|
- **WordPress** → `urls.rest_api` (`wp/v2`), public read. Content is in the posts/pages/categories/media
|
|
89
102
|
the content-model push created; nav/plan come from `content-model.md`. Map each item's **SEO** from its
|
|
90
|
-
`yoast_head_json` into the page `<head>` (title, description, Open Graph, JSON-LD schema)
|
|
103
|
+
`yoast_head_json` into the page `<head>` (title, description, Open Graph, JSON-LD schema) — Yoast is
|
|
104
|
+
installed by default at provision (`site.json → seo.enabled: true`). If `seo.enabled` is `false`
|
|
105
|
+
(Yoast absent), fall back to generating per-page title/description/OG tags from each item's content.
|
|
106
|
+
- **WordPress + WooCommerce** (`site.json → woocommerce.enabled: true`) → the WordPress bullet above **plus**
|
|
107
|
+
the store. Read the catalog over the **public WooCommerce Store API** (`site.json → urls.store_api`,
|
|
108
|
+
`/cms/wp-json/wc/store/v1`, no auth, open CORS): `GET /products` (prices are **integer minor units** on
|
|
109
|
+
`prices.price` with `prices.currency_minor_unit` — divide to display), `GET /products/categories`. Cart,
|
|
110
|
+
coupons and checkout are **client-side** against the Store API with the `Nonce` + `Cart-Token` headers
|
|
111
|
+
(`GET /cart`, `POST /cart/add-item`, `/cart/apply-coupon`, `POST /checkout`) — see
|
|
112
|
+
`../04-content-model/wordpress/woocommerce.md`. **Never embed a consumer key client-side**; the
|
|
113
|
+
storefront is fully public. Blog/pages on the same site still come from `urls.rest_api` (`wp/v2`) + Yoast.
|
|
114
|
+
- **Honour `site.json → woocommerce.payment_enabled`.** It is `false` until the owner enables a payment
|
|
115
|
+
gateway + shipping in wp-admin (that config isn't reachable headlessly — see the provision note). While
|
|
116
|
+
`false`, build the full catalog, product pages and the client-side cart as normal, but render a
|
|
117
|
+
graceful disabled-checkout state (e.g. a disabled "Checkout" with "Checkout isn't set up yet"), **don't
|
|
118
|
+
call `/checkout`**, and don't treat it as a build error. When `true`, wire checkout (`payment_method`
|
|
119
|
+
`"cod"` works out of the box).
|
|
91
120
|
- **Ecommerce** → the **public Hostinger Storefront Core V2 API** (`https://api-ecommerce.hostinger.com/v2`,
|
|
92
121
|
no auth, open CORS), keyed on the **custom sales channel** (`site.json → ecommerce.sales_channel.id`):
|
|
93
122
|
`GET /channels/<scha_*>/products` (prices are **minor units** on variants), `POST /channels/<scha_*>/checkout`
|
|
@@ -20,7 +20,7 @@ description: "Step 7 (validate) of the Hostinger Headless flow. OPTIONAL quick g
|
|
|
20
20
|
`hosting_websites_list-setups { "domain": "<domain>" }`, exact-match the row → `completed`. Anything
|
|
21
21
|
else → not ready; return to the instance barrier, don't deploy.
|
|
22
22
|
|
|
23
|
-
## 2 — Backend API status (WordPress
|
|
23
|
+
## 2 — Backend API status (WordPress / WooCommerce / Ecommerce, always, quick)
|
|
24
24
|
|
|
25
25
|
Hit the live API from `site.json` and confirm it answers **with the content the push created** — a 200
|
|
26
26
|
with an empty catalog means the push didn't land:
|
|
@@ -28,6 +28,9 @@ with an empty catalog means the push didn't land:
|
|
|
28
28
|
- **WordPress:** `GET {urls.rest_api}/posts?per_page=1` → 200 JSON array; check `X-WP-Total` against the
|
|
29
29
|
planned post count, and `GET {urls.rest_api}/media?per_page=1` → `X-WP-Total` matches the planned
|
|
30
30
|
image count (more = duplicates).
|
|
31
|
+
- **WordPress + WooCommerce** (`site.json → woocommerce.enabled`): the WordPress check above **plus**
|
|
32
|
+
`GET {urls.store_api}/products?per_page=100` → 200 with the seeded products and `prices` (minor units);
|
|
33
|
+
count matches the plan. Don't test checkout while `woocommerce.payment_enabled` is `false`.
|
|
31
34
|
- **Ecommerce:** query `urls.storefront_api` for the sales channel → 200 with the seeded products and
|
|
32
35
|
prices *(confirm against the store)*.
|
|
33
36
|
|
|
@@ -116,9 +116,15 @@ hangs, `hosting_nodejs_restart-application { username, domain }` recovers the se
|
|
|
116
116
|
| SSR is live *(server frameworks)* | response headers | `x-powered-by` present, `cache-control: no-store` |
|
|
117
117
|
| Static serves *(static frameworks)* | `GET https://<domain>/` | 200 HTML with real home content |
|
|
118
118
|
| Key routes | a couple of planned routes + one deep route | 200, real content |
|
|
119
|
-
| **Backend survived** *(WordPress
|
|
120
|
-
|
|
121
|
-
> **Only WordPress has a `/cms` on the domain**, so the *Backend
|
|
119
|
+
| **Backend survived** *(WordPress / WooCommerce)* | `GET https://<domain>/cms/wp-json/wp/v2/posts?per_page=1` | 200 |
|
|
120
|
+
|
|
121
|
+
> **Only WordPress (including WordPress + WooCommerce) has a `/cms` on the domain**, so the *Backend
|
|
122
|
+
> survived* check is WordPress-only.
|
|
123
|
+
> - **WordPress + WooCommerce:** also confirm the store survived the deploy —
|
|
124
|
+
> `GET https://<domain>/cms/wp-json/wc/store/v1/products?per_page=1` → 200. There is nothing external to
|
|
125
|
+
> link (no sales-channel step — that's Ecommerce only). **Checkout** stays owner-completed: when
|
|
126
|
+
> `site.json → woocommerce.payment_enabled` is `false`, don't test `/checkout`; a catalog that serves 200
|
|
127
|
+
> is a passing, complete deploy.
|
|
122
128
|
> - **Ecommerce:** the backend is the **Hostinger Ecommerce store**, read over the external Storefront API
|
|
123
129
|
> (`api-ecommerce.hostinger.com`) — nothing a deploy touches lives on this domain. There is no `/cms`;
|
|
124
130
|
> confirm the storefront still fetches products as a frontend check if you like. **Only check that
|
|
@@ -153,6 +159,8 @@ No secrets in `deploy.json`. The `urls.cms` field and the `backend_preserved` ch
|
|
|
153
159
|
**WordPress-only** — adjust the record to the backend:
|
|
154
160
|
|
|
155
161
|
- **WordPress:** keep `urls.cms` and `checks.backend_preserved` as shown.
|
|
162
|
+
- **WordPress + WooCommerce:** keep `urls.cms` + `checks.backend_preserved` (it *is* WordPress), and add
|
|
163
|
+
`urls.store_api` from `site.json`; no external link step.
|
|
156
164
|
- **Ecommerce:** omit `urls.cms`/`backend_preserved`; record the store URLs instead (`urls.storefront_api`,
|
|
157
165
|
`urls.store_admin` from `site.json`) and link the custom sales channel to the live domain —
|
|
158
166
|
`ecommerce_sales-channels_update { store_id, sales_channel_id, url }` (see the ecommerce provision step).
|
|
@@ -17,8 +17,9 @@ already checked this — this is a quick re-confirm, not a full re-run):
|
|
|
17
17
|
- **Main site:** `GET https://<domain>/` → 200 (Next.js SSR: `x-powered-by: Next.js`; Astro SSG: static
|
|
18
18
|
HTML with real content).
|
|
19
19
|
- **WordPress admin:** `GET {urls.wp_admin}` → reachable (a login page, 200/302), not 404.
|
|
20
|
-
- **Backend API:** `GET {urls.rest_api}/posts?per_page=1` → 200 (WordPress);
|
|
21
|
-
|
|
20
|
+
- **Backend API:** `GET {urls.rest_api}/posts?per_page=1` → 200 (WordPress); for a **WooCommerce** store
|
|
21
|
+
(`site.json → woocommerce.enabled`) also `GET {urls.store_api}/products?per_page=1` → 200; or the
|
|
22
|
+
storefront API for the sales channel → 200 (Ecommerce).
|
|
22
23
|
|
|
23
24
|
If a check fails, say so in the outcome paragraph and don't claim the site is live.
|
|
24
25
|
|
|
@@ -61,8 +62,13 @@ Write it in this order:
|
|
|
61
62
|
auto-login redirect URL** — `wordpress_login_create-links { username, software: <site.json
|
|
62
63
|
wordpress.install_id> }` returns a temporary link that logs the user straight into wp-admin. Give
|
|
63
64
|
that URL as the admin link (it lands on `/cms/wp-admin`), so the user never needs a password. Also
|
|
64
|
-
note the plain `urls.wp_admin` as a fallback. **Never print or store a password.** For
|
|
65
|
-
|
|
65
|
+
note the plain `urls.wp_admin` as a fallback. **Never print or store a password.** For a
|
|
66
|
+
**WordPress + WooCommerce** store, this *same* wp-admin login is the store admin (wp-admin →
|
|
67
|
+
WooCommerce → Products/Orders) — do **not** use the Ecommerce `store_admin` path. **Call out the one
|
|
68
|
+
setup step under *Gaps / follow-ups*:** when `site.json → woocommerce.payment_enabled` is `false`,
|
|
69
|
+
the owner must enable a payment method + a shipping zone in WooCommerce → Settings before checkout
|
|
70
|
+
works (the catalog and cart already work). For a Hostinger **Ecommerce** store, link the store admin
|
|
71
|
+
from `urls.store_admin` instead.
|
|
66
72
|
- **hPanel site dashboard:** `https://hpanel.hostinger.com/websites/<domain>` (the headless website
|
|
67
73
|
is installed by now).
|
|
68
74
|
- **Onboarding (resume):** `https://hpanel.hostinger.com/headless-onboarding/<order_id>/<username>/`
|