Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Agents
daun/statamic-multisite-field
claude-code
cursor
statamic
fieldtypes
multisite
vue
publish-container
addon-development
vitest

multisite fieldtype: wraps one child field, stores {sitehandle: value}, augments to the current site's value (optional inheritance). multisiteswitcher: runtime-only site toggle, stores nothing.

Install
php artisan boost:add-skill daun/statamic-multisite-field

Save this content to: AGENTS.md

# AGENTS.md

`multisite` fieldtype: wraps one child field, stores `{site_handle: value}`,
augments to the current site's value (optional inheritance). `multisite_switcher`:
runtime-only site toggle, stores nothing.

## Commands

```bash
composer test && composer lint && composer analyse   # Pest, Pint, PHPStan
pnpm test                                            # Vitest (tests/js/)
pnpm build                                           # resources/dist is committed — rebuild after JS changes
```

## Invariants

- **Storage**: `{site: rawChildValue}`, no inner-handle level. Empty values are
  pruned on save; a missing key means "inherit". In single-site mode values are
  stored flat (no pruning); `normalizeValue()` handles both shapes on read.
- **Meta contract** (PHP `preload()` ↔ `MultisiteFieldtype.vue`): change both
  sides together. `fields.<site>`/`new` are the child's own meta; Vue wraps them
  as `{[innerHandle]: meta}`.
- **Child renders in an isolated `PublishContainer`** per site, not the ambient
  one (site-keyed shape doesn't match ambient paths). Visited sites stay mounted
  behind `v-show`; remounting kills editor performance.
- **Props passed to `PublishContainer` must be referentially stable** (cached
  computeds). It re-emits on identity change, so fresh objects loop forever.
- **Active site is a shared singleton** (`resources/js/activeSite.js`), never
  field meta, so switching doesn't dirty the form.
- **Validation/error keys**: PHP uses `{handle}.{site}[.{rest}]`; Vue remaps
  ambient errors to `<innerHandle>[.<rest>]`. Keep the two in sync.
- **`placeholder` is display-only.** It never enters augmentation, stored data or
  validation. Resolution order: site value, then default site (if `inherit`),
  then the sibling `fallback` field.
- **Wrapped field actions** come from `field.$.refs.fieldtype`. `setupState` is
  empty in production builds; the test stub in `tests/js/setup.js` mimics prod.
- **Addon CSS is plain CSS, not Tailwind.** `resources/css/addon.css` holds the
  few custom rules. Tailwind classes in templates must already exist in core CP CSS:
  `grep -c '\.CLASS' vendor/statamic/cms/resources/dist/build/assets/*.css`.
- Site labels are resolved in PHP (`SiteLabels`, config file). Vue uses
  `siteLabel()`/`siteShortLabel()`, not `site.name`.

## Gotchas

- Vitest needs its own `vitest.config.js` (plain vue plugin); the prod Vite
  config rewrites `vue`/`@statamic` imports.
- Verify assumed Statamic core APIs in `vendor/` before coding against them.

AGENTS.md

multisite fieldtype: wraps one child field, stores {site_handle: value}, augments to the current site's value (optional inheritance). multisite_switcher: runtime-only site toggle, stores nothing.

Commands

composer test && composer lint && composer analyse   # Pest, Pint, PHPStan
pnpm test                                            # Vitest (tests/js/)
pnpm build                                           # resources/dist is committed — rebuild after JS changes

Invariants

  • Storage: {site: rawChildValue}, no inner-handle level. Empty values are pruned on save; a missing key means "inherit". In single-site mode values are stored flat (no pruning); normalizeValue() handles both shapes on read.
  • Meta contract (PHP preload() ↔ MultisiteFieldtype.vue): change both sides together. fields.<site>/new are the child's own meta; Vue wraps them as {[innerHandle]: meta}.
  • Child renders in an isolated PublishContainer per site, not the ambient one (site-keyed shape doesn't match ambient paths). Visited sites stay mounted behind v-show; remounting kills editor performance.
  • Props passed to PublishContainer must be referentially stable (cached computeds). It re-emits on identity change, so fresh objects loop forever.
  • Active site is a shared singleton (resources/js/activeSite.js), never field meta, so switching doesn't dirty the form.
  • Validation/error keys: PHP uses {handle}.{site}[.{rest}]; Vue remaps ambient errors to <innerHandle>[.<rest>]. Keep the two in sync.
  • placeholder is display-only. It never enters augmentation, stored data or validation. Resolution order: site value, then default site (if inherit), then the sibling fallback field.
  • Wrapped field actions come from field.$.refs.fieldtype. setupState is empty in production builds; the test stub in tests/js/setup.js mimics prod.
  • Addon CSS is plain CSS, not Tailwind. resources/css/addon.css holds the few custom rules. Tailwind classes in templates must already exist in core CP CSS: grep -c '\.CLASS' vendor/statamic/cms/resources/dist/build/assets/*.css.
  • Site labels are resolved in PHP (SiteLabels, config file). Vue uses siteLabel()/siteShortLabel(), not site.name.

Gotchas

  • Vitest needs its own vitest.config.js (plain vue plugin); the prod Vite config rewrites vue/@statamic imports.
  • Verify assumed Statamic core APIs in vendor/ before coding against them.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums