afv-library/skills/generating-webapplication-metadata/SKILL.md
k-j-kim a779945206
Rename webapp/webapplication to UI bundle in skills (#129)
* Split generating-webapp-metadata into single-purpose skills

Extract the deployment sequence into a new deploying-webapp skill so each
webapp skill describes exactly one actionable goal. This improves agent
skill selection accuracy by eliminating multi-concern descriptions.

- generating-webapp-metadata: now focused on scaffolding, bundle config, CSP
- deploying-webapp: new skill for the 7-step deployment sequence

* Rename -webapp- skill directories and references to -webapplication-

Rename all 7 webapp skill directories to use the full "webapplication"
entity name. Update frontmatter name fields, cross-skill references,
and descriptive prose. Package names and CLI commands are preserved
as-is since those are actual identifiers.
2026-03-30 11:49:19 -05:00

107 lines
4.6 KiB
Markdown

---
name: generating-webapplication-metadata
description: "Scaffold new Salesforce web applications and configure their metadata — sf webapp generate, WebApplication bundles (meta XML, webapplication.json with routing/headers/outputDir), and CSP Trusted Sites for external domains. Use whenever creating a new web application, setting up web application metadata structure, configuring routing or headers, setting outputDir, adding external domains that need CSP registration, or editing bundle configuration. Triggers on: create web application, create webapp, new app, sf webapp generate, metadata, webapplication.json, CSP, trusted site, bundle configuration, meta XML, routing config, external domain, headers config, outputDir."
---
# Web Application Metadata
## Scaffolding a New Web Application
Use `sf webapp generate` to create new apps — not create-react-app, Vite, or other generic scaffolds.
**Web application name (`-n`):** Alphanumerical only — no spaces, hyphens, underscores, or special characters. Example: `CoffeeBoutique` (not `Coffee Boutique`).
After generation:
1. Replace all default boilerplate — "React App", "Vite + React", default `<title>`, placeholder text
2. Populate the home page with real content (landing section, banners, hero, navigation)
3. Update navigation and placeholders (see the `generating-webapplication-ui` skill)
Always install dependencies before running any scripts in the web application directory.
---
## WebApplication Bundle
A WebApplication bundle lives under `webapplications/<AppName>/` and must contain:
- `<AppName>.webapplication-meta.xml` — filename must exactly match the folder name
- A build output directory (default: `dist/`) with at least one file
### Meta XML
Required fields: `masterLabel`, `version` (max 20 chars), `isActive` (boolean).
Optional: `description` (max 255 chars).
### webapplication.json
Optional file. Allowed top-level keys: `outputDir`, `routing`, `headers`.
**Constraints:**
- Valid UTF-8 JSON, max 100 KB
- Root must be a non-empty object (never `{}`, arrays, or primitives)
**Path safety** (applies to `outputDir` and `routing.fallback`): Reject backslashes, leading `/` or `\`, `..` segments, null/control characters, globs (`*`, `?`, `**`), and `%`. All resolved paths must stay within the bundle.
#### outputDir
Non-empty string referencing a subdirectory (not `.` or `./`). Directory must exist and contain at least one file.
#### routing
If present, must be a non-empty object. Allowed keys: `rewrites`, `redirects`, `fallback`, `trailingSlash`, `fileBasedRouting`.
- **trailingSlash**: `"always"`, `"never"`, or `"auto"`
- **fileBasedRouting**: boolean
- **fallback**: non-empty string satisfying path safety; target file must exist
- **rewrites**: non-empty array of `{ route?, rewrite }` objects — e.g., `{ "route": "/app/:path*", "rewrite": "/index.html" }`
- **redirects**: non-empty array of `{ route?, redirect, statusCode? }` objects — statusCode must be 301, 302, 307, or 308
#### headers
Non-empty array of `{ source, headers: [{ key, value }] }` objects.
**Example:**
```json
{
"routing": {
"rewrites": [{ "route": "/app/:path*", "rewrite": "/index.html" }],
"trailingSlash": "never"
},
"headers": [
{
"source": "/assets/**",
"headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
}
]
}
```
**Never suggest:** `{}` as root, empty `"routing": {}`, empty arrays, `[{}]`, `"outputDir": "."`, `"outputDir": "./"`.
---
## CSP Trusted Sites
Salesforce enforces Content Security Policy headers. Any external domain not registered as a CSP Trusted Site will be blocked (images won't load, API calls fail, fonts missing).
### When to Create
Whenever the app references a new external domain: CDN images, external fonts, third-party APIs, map tiles, iframes, external stylesheets.
### Steps
1. **Identify external domains** — extract the origin (scheme + host) from each external URL in the code
2. **Check existing registrations** — look in `force-app/main/default/cspTrustedSites/`
3. **Map resource type to CSP directive:**
| Resource Type | Directive Field |
|--------------|----------------|
| Images | `isApplicableToImgSrc` |
| API calls (fetch, XHR) | `isApplicableToConnectSrc` |
| Fonts | `isApplicableToFontSrc` |
| Stylesheets | `isApplicableToStyleSrc` |
| Video / audio | `isApplicableToMediaSrc` |
| Iframes | `isApplicableToFrameSrc` |
Always also set `isApplicableToConnectSrc` to `true` for preflight/redirect handling.
4. **Create the metadata file** — follow `implementation/csp-metadata-format.md` for the `.cspTrustedSite-meta.xml` format. Place in `force-app/main/default/cspTrustedSites/`.