← Files WixARCHIVED FILE

skills/wix-headless-templates/portfolio/seed/SEED.md

5.07 KB · Oct 8, 2026 · 12:02 UTC

↓ Download file

See the change to this file →

# Portfolio — seeding

Seed by **running `seed-portfolio.mjs` with a plan file** — don't hand-write the REST calls.
The script mints its own site token via the Wix CLI (logged-in session + `wix.config.json`
required), installs the Portfolio app if needed, and creates everything in the right order:
collections first (a project's `collectionIds` are NOT validated — a wrong id silently
orphans the project), then projects, gallery items, and covers.

```bash
# from the project root (where wix.config.json lives):
node <SKILL_ROOT>/templates/portfolio/seed/seed-portfolio.mjs plan.json
```

`plan.json` is plain data — write it from the brief. **Default to 2 collections × 2 projects
each** (the seed shows the shape; the owner adds the rest in the dashboard) and make them
exercise the UI: every collection and project gets a cover, every project gets 2–3 gallery
`items` (a portfolio without images looks broken), and a couple of projects get `details`
rows (Role, Year, Client…).

```json
{
  "collections": [
    { "title": "Brand Identity", "description": "Logo systems and visual identities.",
      "coverImageUrl": "https://…" },
    { "title": "Editorial", "description": "Print and digital editorial design.",
      "coverImageUrl": "https://…" }
  ],
  "projects": [
    { "title": "Northwind Rebrand", "description": "Full identity refresh for a logistics firm.",
      "collection": "Brand Identity",
      "details": [ { "label": "Role", "text": "Brand & Art Direction" }, { "label": "Year", "text": "2025" } ],
      "coverImageUrl": "https://…",
      "items": [
        { "sortOrder": 1, "title": "Logo system", "imageUrl": "https://…" },
        { "sortOrder": 2, "title": "Stationery", "imageUrl": "https://…" }
      ] },
    { "title": "Harbor Coffee", "description": "Packaging and label suite.",
      "collection": "Brand Identity", "coverImageUrl": "https://…",
      "items": [ { "sortOrder": 1, "title": "Label set", "imageUrl": "https://…" } ] },
    { "title": "Field Notes Quarterly", "description": "Magazine layout and typography.",
      "collection": "Editorial", "coverImageUrl": "https://…",
      "items": [ { "sortOrder": 1, "title": "Spread", "imageUrl": "https://…" } ] },
    { "title": "City Guides", "description": "Travel series covers.",
      "collection": "Editorial", "coverImageUrl": "https://…",
      "items": [ { "sortOrder": 1, "title": "Covers", "imageUrl": "https://…" } ] }
  ]
}
```

- `collection` — a collection **title from this plan**; resolved to its created id. A project
  without one belongs to no collection (reachable only from an all-projects list).
- `details` — optional `[{ label, text }]` rows; render on the project page. Omit for none.
- Every image field's default is a prompt (`coverImagePrompt` / `items[].imagePrompt` —
  AI-generated, ~1 Wix AI credit per image, account-billed): brand-contextual — subject,
  aesthetic/mood, palette, lighting — always ending "no text, no watermarks". At least one image in the set shows the real subject of the business — the actual product/space/service, not abstract decoration. For an asset the user actually supplied
  use a path (`coverImagePath` / `items[].imagePath` — a file on this machine, uploaded to
  Wix Media) or a url (`coverImageUrl` / `items[].imageUrl` — their own hosted URL; verify it
  with `curl -sI` → 200) — never a stock-photo or guessed URL. All images —
  covers and gallery items alike — resolve in one parallel wave and never block the seed; a
  failed image skips just that item/cover. The **cover** is the
  listing thumbnail; **items** are the detail-page gallery — separate entities, both wanted.
  If a project has only a cover, reuse its url as item 1 so the gallery isn't empty.
- `sortOrder` (1, 2, 3…) sets the gallery render order.
- `hidden` defaults to shown — omit it; send `hidden: true` only to hide an entity.
- Gallery items seed as images only; the owner adds videos in the dashboard.
- A fresh Portfolio install ships sample content ("My Portfolio" + sample projects). **Seeding
  is additive — never delete or overwrite existing content**; if removing the samples seems
  wanted, ask the owner first.

## Supplied content

The general rules are in `templates/shared/SUPPLIED-CONTENT.md`. For a portfolio, each project the
user lists is one entry. Its title becomes `title`; its category or series becomes `collection`
(and joins the `collections` list); client, role, year and similar facts become `details`; their
cover image becomes `coverImageUrl`; their project images become `items` in the order given. A
photo with no caption gets its file name as `title`.

## Escape hatch — individual functions
`setupPortfolio` composes exported steps — `installPortfolioApp`, `createCollections`,
`createProjects`, `importImage`, `attachProjectCovers`, `attachCollectionCovers`,
`createProjectItems`, `listCollections`, `listProjects`, plus `makeCtx()` — import them only
for a partial re-seed.

## Reference
Unexpected shape or an uncovered operation → read the live Wix API reference; every call the script
makes carries a `docs:` line with its reference page.

SHA-256: dac80406f5e9ad7a24c7323d71943559760997bb6c25f9baa9c21ca5e4ce0c3d