lwr-site-development
Use this skill when building or customizing sites on the Lightning Web Runtime (LWR) in Experience Cloud — including component authoring, custom theming with --dxp hooks, layout components, and publish lifecycle management. Trigger keywords: build LWR site Experience Cloud, Lightning Web Runtime custom theme, LWR component development community, Build Your Own LWR template, Microsite LWR, lightningCommunity__Theme_Layout, --dxp styling hooks. NOT for Aura-based communities (Build Your Own Aura template). NOT for standard Experience Builder drag-and-drop configuration without code.
Best use case
lwr-site-development is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use this skill when building or customizing sites on the Lightning Web Runtime (LWR) in Experience Cloud — including component authoring, custom theming with --dxp hooks, layout components, and publish lifecycle management. Trigger keywords: build LWR site Experience Cloud, Lightning Web Runtime custom theme, LWR component development community, Build Your Own LWR template, Microsite LWR, lightningCommunity__Theme_Layout, --dxp styling hooks. NOT for Aura-based communities (Build Your Own Aura template). NOT for standard Experience Builder drag-and-drop configuration without code.
Teams using lwr-site-development should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/lwr-site-development/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How lwr-site-development Compares
| Feature / Agent | lwr-site-development | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use this skill when building or customizing sites on the Lightning Web Runtime (LWR) in Experience Cloud — including component authoring, custom theming with --dxp hooks, layout components, and publish lifecycle management. Trigger keywords: build LWR site Experience Cloud, Lightning Web Runtime custom theme, LWR component development community, Build Your Own LWR template, Microsite LWR, lightningCommunity__Theme_Layout, --dxp styling hooks. NOT for Aura-based communities (Build Your Own Aura template). NOT for standard Experience Builder drag-and-drop configuration without code.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# LWR Site Development
Use this skill when building components, custom themes, or page/theme layouts for Experience Cloud sites powered by the Lightning Web Runtime (LWR). This covers both the Build Your Own (LWR) and Microsite (LWR) templates and addresses the unique behaviors — publish-time freeze, Lightning Web Security, and --dxp theming hooks — that distinguish LWR from Aura-based sites.
---
## Before Starting
Gather this context before working on anything in this domain:
- Confirm the site template is **Build Your Own (LWR)** or **Microsite (LWR)** — not the legacy Aura-based Build Your Own template. Aura components are completely unsupported in LWR sites.
- Confirm Digital Experiences (formerly Communities) is enabled in the org.
- Know whether the site needs authenticated access, public/guest access, or both — this affects sharing model, guest user permissions, and which `@salesforce` modules are available.
- Confirm the org is Winter '23 or later. New LWR sites are enhanced LWR sites by default (no `/s` in URL, hosted on the enhanced sites and content platform).
- Identify the component role: drag-and-drop page component, theme layout, page layout, or standalone LWC.
---
## Core Concepts
### LWR Templates Are LWC-Only
The Build Your Own (LWR) and Microsite (LWR) templates are based exclusively on the Lightning Web Components (LWC) programming model. Aura components are not supported anywhere in LWR sites — not as page components, theme layouts, or page layouts. This is a hard platform constraint, not a configuration choice.
The Build Your Own (LWR) template provides only essential pages (Home, Error, Login, Forgot Password, Register) and minimal components. Teams must build all content and layout components themselves as LWC bundles. The Microsite (LWR) template includes a responsive layout and pre-configured pages, making it suited for landing pages and event sites that require little additional customization.
### Publish-Time Freeze and Static Serving
LWR sites use a fundamentally different serving model from Aura sites. When a site is published, all JavaScript resources (components, views, framework scripts) are generated, frozen, and served as static, immutable, cacheable resources. The live site serves these frozen resources — it does not fetch current component code dynamically.
This means: **any change to a component, managed package component, custom label, or Apex method signature requires republishing the site before it takes effect.** The preview in Experience Builder always shows the latest code, but the live site does not update until republished.
Practical consequences:
- Bug fixes in LWC code are not live until the site is republished.
- Managed package upgrades are not live until the site is republished.
- Updated custom labels are not live until the site is republished.
- Apex method signature changes can break existing components on the live site if not republished promptly.
- Generated framework scripts are cached for 150 days. Static resources and content assets are cached for 1 day.
### Lightning Web Security (LWS) vs. Lightning Locker
LWR sites use Lightning Web Security (LWS) instead of Lightning Locker. LWS is stricter in some dimensions and more permissive in others:
| Behavior | LWS on LWR sites |
|---|---|
| Cross-namespace component imports | Supported — LWC components can import from other namespaces via composition or extension. |
| Global objects (`document`, `window`, `element`) | Exposed directly — no longer wrapped in secure proxies, so standard DOM APIs work within a namespace. |
| Third-party library integration | Easier — analytics and charting libraries can interact with DOM elements more naturally. |
| Restricted DOM properties | `document.domain`, `document.location`, `window.location`, and `window.top` are unsupported. |
The org-level `Use Lightning Web Security` setting in Session Settings has **no effect** on LWR sites. LWS is always active at the site level, regardless of the org setting.
Existing components built for Aura sites or Lightning Experience may rely on Locker-specific patterns. Test them in an LWR site context before deploying.
### Component Targets and js-meta.xml Registration
Every LWC component used in an LWR site must declare its role via `targets` in its `js-meta.xml` configuration file.
| Target | Role |
|---|---|
| `lightningCommunity__Page` | Drag-and-drop component for use on site pages in Experience Builder |
| `lightningCommunity__Page_Layout` | Page layout (defines regions/slots for page content) |
| `lightningCommunity__Theme_Layout` | Theme layout (defines header, footer, and main content slot) |
| `lightningCommunity__Default` | Used alongside one of the above to expose editable properties in Experience Builder |
For a component to appear in the Components panel in Experience Builder, it must set `isExposed` to `true` and declare `lightningCommunity__Page` in `targets`.
For a component to expose editable properties, it must also declare `lightningCommunity__Default` in `targets` and define `property` elements in a `targetConfig` block. Supported property types: String, Integer, Boolean, Color, Picklist.
Theme layout components must include a default (unnamed) `<slot></slot>` element in their template to define where the main content renders. Named slots define header and footer regions.
Page layout components must declare slot names using `@slot` JSDoc annotations directly before the class declaration.
### --dxp Styling Hooks for Custom Theming
LWR sites use `--dxp` CSS custom properties (styling hooks) for theming. These are global hooks that cascade to base and custom components throughout the site. Setting a single `--dxp` hook can affect dozens of individual component properties at once.
Key hook families:
- `--dxp-g-brand` / `--dxp-g-brand-contrast` — primary brand color (buttons, links, focus states)
- `--dxp-g-root` / `--dxp-g-root-contrast` — page/section background and foreground color
- `--dxp-g-neutral`, `--dxp-g-destructive`, `--dxp-g-success` — semantic colors (configure only via head markup, not the Theme panel)
- Text hooks — heading, body, button, link, and form text styling
- Site spacing hooks — maximum content width, section padding, column and component spacing
In custom components, reference `--dxp` hooks using CSS `var()`:
```css
.my-custom-button {
background-color: var(--dxp-g-brand);
color: var(--dxp-g-brand-contrast);
}
```
The Theme panel in Experience Builder declaratively maps to `--dxp` hooks. When the Theme panel is updated, all components referencing those hooks update automatically. For fine-grained overrides, use `--slds-c` hooks alongside `--dxp` hooks.
The branding stylesheets (`dxp-styling-hooks.min.css`, `dxp-site-spacing-styling-hooks.min.css`, etc.) are automatically included in LWR sites created in Summer '21 or later. Older sites must add these to the Head Markup manually.
---
## Common Patterns
### Custom Theme Layout with Brand-Aligned Header and Footer
**When to use:** The team needs a consistent header and footer across all site pages, with full control over navigation, branding, and layout regions — and the default out-of-the-box theme layout does not meet design requirements.
**How it works:**
1. Create an LWC component with target `lightningCommunity__Theme_Layout` in js-meta.xml.
2. Add a default `<slot></slot>` in the template for main content. Add named slots for header and footer regions.
3. Use `@slot` JSDoc annotations before the class declaration to register region names with Experience Builder.
4. Add `data-f6-region` attributes to major layout regions for keyboard/screen reader accessibility.
5. In the component CSS, use `--dxp` hooks for all brand colors and spacing to maintain Theme panel responsiveness.
6. Register the component in a Theme Layout under Settings > Theme in Experience Builder, and assign the theme layout to site pages.
**Why not the alternative:** Hard-coding colors instead of using `--dxp` hooks breaks the Theme panel linkage. Any future brand update requires manual CSS edits across all components instead of a single Theme panel change.
### Page Component with Editable Properties for Experience Builder
**When to use:** A developer needs to build a reusable content component that non-developer site admins can configure directly in Experience Builder without code changes.
**How it works:**
1. Create the LWC component with its business logic in JavaScript and markup in HTML.
2. In js-meta.xml, set `isExposed` to `true`, declare `lightningCommunity__Page` and `lightningCommunity__Default` in `targets`.
3. Define configurable properties in a `targetConfig` for the `lightningCommunity__Default` target. Use camelCase property names (never PascalCase — it breaks coercion).
4. Declare `@api` properties in the JavaScript file matching the js-meta.xml property names.
5. For string properties that need translation in multilingual sites, set `translatable="true"` in the property definition.
6. For screen-responsive properties, set `screenResponsive="true"` and `exposedTo="css"`, then use `--dxp-c-{size}-{property-name}` CSS variables for media queries.
**Why not the alternative:** Skipping `lightningCommunity__Default` means the component appears in the panel but exposes no configurable properties. Site admins must file change requests for any content variation instead of self-serving through Experience Builder.
---
## Decision Guidance
| Situation | Recommended Approach | Reason |
|---|---|---|
| Need a consistent header/footer across all pages | Create a `lightningCommunity__Theme_Layout` LWC component | Theme layouts define site-wide structure; assigning one per page type is the correct LWR pattern |
| Need different layouts for different page types | Create multiple `lightningCommunity__Page_Layout` LWC components | Page layouts control the slot regions for content; assign per-page in Experience Builder |
| Need brand-responsive colors in a custom component | Use `var(--dxp-g-brand)` and related `--dxp` hooks in component CSS | Hooks cascade from the Theme panel; changing brand color once propagates everywhere |
| Need to integrate a third-party analytics library | Use the `<x-oasis-script>` privileged script tag in Head Markup | LWS allows standard DOM interaction; `<x-oasis-script>` is the supported entry point for global scripts |
| Need navigation between site pages | Import `NavigationMixin` from `lightning/navigation` using `comm__namedPage` or `standard__recordPage` | LWR templates do not support Aura navigation APIs or `standard__namedPage` — use `comm__namedPage` instead |
| Need authenticated and guest access on the same site | Use LWR sites created in Winter '23 or later (authenticated by default, supports public pages) | Pre-Winter '23 unauthenticated sites lack login/authentication support entirely |
| Site shows stale component behavior after a code fix | Republish the site | LWR sites serve frozen, publish-time resources; the live site does not pick up changes until republished |
| Need to support Aura components on the site | Migrate to LWC or use a standard Aura-based template | Aura components are completely unsupported in LWR sites; there is no compatibility layer |
---
## Recommended Workflow
Step-by-step instructions for an AI agent or practitioner working on this task:
1. **Confirm site template and org context** — Verify the target site uses Build Your Own (LWR) or Microsite (LWR). Confirm Digital Experiences is enabled. Check whether the site was created in Winter '23 or later (enhanced LWR site with no `/s` URL). Identify whether guest/public access is needed (affects guest user preference settings).
2. **Plan component roles and targets** — For each component, determine its role: drag-and-drop content (`lightningCommunity__Page`), page layout (`lightningCommunity__Page_Layout`), or theme layout (`lightningCommunity__Theme_Layout`). Theme and page layout components require slot-based region definitions and `@slot` JSDoc annotations.
3. **Scaffold the LWC bundle and configure js-meta.xml** — Create the component folder with `.html`, `.js`, `.css`, and `.js-meta.xml`. Set `isExposed: true` and the correct `targets`. If the component needs editable properties, add `lightningCommunity__Default` to targets and define `property` elements in `targetConfig`. Use camelCase for all property names.
4. **Implement CSS theming with --dxp hooks** — In the component `.css` file, use `var(--dxp-g-brand)`, `var(--dxp-g-root)`, and related hooks for all brand-dependent colors and spacing. Avoid hardcoded hex values for brand colors. For screen-responsive properties, use the `--dxp-c-{size}-{property}` CSS variable pattern with standard breakpoints (l = desktop, m = tablet ≤64em, s = mobile ≤47.9375em).
5. **Register and configure in Experience Builder** — Deploy the component to the org. In Experience Builder, assign theme layout components under Settings > Theme. Assign page layout components via page settings. Drag-and-drop components appear automatically in the Components panel. Configure editable properties through the component's property panel.
6. **Validate and republish before each delivery** — After every code change, republish the site so the live static bundle includes the updated component. Verify behavior on the live site, not just the Experience Builder preview. Confirm that no Aura component references exist in the deployment. If Apex method signatures changed, republish immediately to prevent live site breakage.
---
## Review Checklist
Run through these before marking work in this area complete:
- [ ] All components declare the correct `lightningCommunity__*` targets in js-meta.xml — no Aura targets or patterns used
- [ ] No Aura components referenced anywhere in the LWR site deployment
- [ ] Theme layout components include a default unnamed `<slot></slot>` and named slots for header/footer regions
- [ ] Page layout components have `@slot` JSDoc annotations before the class declaration
- [ ] All brand-dependent colors use `--dxp` CSS hooks rather than hardcoded values
- [ ] Property names in js-meta.xml use camelCase (not PascalCase)
- [ ] Navigation uses `lightning/navigation` with `comm__namedPage` — no Aura navigation API usage
- [ ] Site has been republished after all component or schema changes
- [ ] Guest user preferences are configured if any public pages exist
- [ ] LWS restrictions verified: no `document.domain`, `document.location`, `window.location`, or `window.top` usage
---
## Salesforce-Specific Gotchas
Non-obvious platform behaviors that cause real production problems:
1. **Publish-time freeze catches teams off guard** — In Aura sites, component changes go live immediately. In LWR sites, the live site serves the frozen bundle from the last publish. A bug fix deployed to the org does nothing for live site users until the site is republished. Teams relying on the Experience Builder preview (which always shows current code) do not notice this until they check the live site.
2. **LWS restriction breakage is silent in preview but fails on live** — The Experience Builder preview environment may handle restricted DOM APIs differently from the live LWS enforcement context. Components that access `window.location` or `document.domain` may appear to work in development but produce runtime errors on the live site. Test LWS compliance specifically on a published site, not just in preview.
3. **Dynamic component imports must be statically analyzable** — LWR sites support dynamic LWC imports, but only statically analyzable ones. `import("c/myComponent")` works. `import("c/" + name)` or `import("c/" + componentVariable)` do not work and fail silently or throw at runtime. All dynamic import paths must be literal strings.
---
## Output Artifacts
| Artifact | Description |
|---|---|
| LWC component bundle | `.html`, `.js`, `.css`, `.js-meta.xml` with correct `lightningCommunity__*` targets for Experience Builder registration |
| Theme layout component | LWC with `lightningCommunity__Theme_Layout` target, default slot, named header/footer slots, and `data-f6-region` attributes |
| Page layout component | LWC with `lightningCommunity__Page_Layout` target and `@slot` JSDoc annotations |
| --dxp CSS theming | Component `.css` using `var(--dxp-g-brand)` and related hooks for brand-responsive styling |
| Publish checklist | Ordered list of changes that require site republish before going live |
---
## Related Skills
- `flow-for-experience-cloud` — when flows are embedded in LWR site pages; LWR has specific compatibility requirements for screen flow components
- `navigation-and-routing` — for `lightning/navigation` usage, `comm__namedPage` vs `standard__recordPage` decisions, and URL generation best practicesRelated Skills
data-cloud-activation-development
Use this skill when building developer-driven Data Cloud activation surfaces: webhook Data Action Targets with HMAC-SHA256 signing, Salesforce Platform Event data actions, Data Cloud-Triggered Flows on DMO insert, or Marketing Cloud journey triggers. Triggers on: webhook data action target, Data Cloud triggered Flow not firing, HMAC secret key for data action, platform event from Data Cloud, DMO insert trigger. NOT for configuring standard admin-level Activation Targets (SFTP, ad platform segment publishing, CRM segment activation) — those require admin configuration skills, not this developer extensibility skill.
composite-api-patterns
Use when designing, implementing, or troubleshooting Salesforce Composite API requests — covering the /composite/ resource with cross-subrequest referenceId wiring, /composite/sobjects/ bulk CRUD, /composite/tree/ hierarchical inserts, and /composite/batch/ independent subrequest bundling. Triggers: 'composite API', 'sObject Tree', 'sObject Collection', 'composite batch', 'subrequest', 'referenceId', 'allOrNone', 'parent child insert one call', 'bulk CRUD same object', 'batch API requests'. NOT for single REST API calls, Bulk API 2.0 large-data-load jobs, GraphQL API queries, Metadata API deployments, or custom Apex REST endpoints.
unlocked-package-development
Use this skill when designing, creating, versioning, or installing unlocked packages: package directory configuration in sfdx-project.json, namespace management, package dependencies, version lifecycle (beta vs. released), ancestor versions, installation keys, and subscriber installation via sf CLI or Package Install UI. NOT for 2GP managed packages (ISV packaging with namespaces, push upgrades, or AppExchange listings), 1GP managed packages, change set deployments, or scratch org setup.
package-development-strategy
Use this skill when deciding between Salesforce package development approaches — unmanaged, unlocked, 1GP managed, or 2GP managed — including namespace selection, ISV distribution requirements, upgrade path design, and AppExchange packaging strategy. Trigger keywords: should I use managed or unlocked package, Salesforce package type selection, 2GP vs 1GP managed package, namespace decision Salesforce, ISV AppExchange packaging, unlocked package strategy. NOT for individual package creation steps, scratch org setup, or day-to-day package version build commands.
multi-package-development
Designing, orchestrating, and maintaining multi-package architectures in Salesforce DX: dependency DAG design, layered package decomposition, install ordering, cross-package API contracts, mono-repo vs. multi-repo layout, and CI/CD pipeline sequencing for projects with two or more unlocked or managed packages. NOT for single-package creation or versioning (see unlocked-package-development), 2GP managed-package ISV workflows (see second-generation-managed-packages), or change-set deployments.
managed-package-development
Use when building or maintaining Salesforce first-generation managed packages (1GP) for ISV distribution — covers namespace registration, packaging org structure, PostInstall/UninstallHandler Apex interface, push upgrades, Flow version management, and subscriber org considerations. NOT for second-generation managed packages (2GP), unlocked packages, or AppExchange listing setup.
multi-site-architecture
Use when designing a strategy for multiple Experience Cloud sites within one Salesforce org, selecting a domain and URL pattern, planning shared LWC component libraries, designing cross-site navigation, managing the org's 100-site quota, or deciding between multi-site vs multi-org for portal needs. Trigger phrases: 'multiple Experience Cloud sites architecture', 'multi-portal strategy Salesforce', 'cross-site navigation Experience Cloud', 'domain strategy community portals', 'shared components across sites', 'how many Experience Cloud sites can I have', 'customer and partner portal same org', 'regional sub-portals Salesforce'. NOT for single Experience Cloud site setup (use admin/experience-cloud-site-setup). NOT for Experience Cloud page layout or component development in isolation. NOT for multi-org strategy (use architect/multi-org-strategy).
cti-adapter-development
Use when building or debugging a browser-based CTI softphone adapter using the Salesforce Open CTI JavaScript API — covers callcenter.xml definition, Lightning utility item registration, core API methods (enableClickToDial, onClickToDial, screenPop, setSoftphonePanelHeight, saveLog), call logging as Task, and the lightning-click-to-dial LWC component. NOT for Service Cloud Voice Amazon Connect setup, Omni-Channel routing configuration, or CTI adapter AppExchange package selection.
ampscript-development
Use this skill when writing, debugging, or reviewing AMPscript in Marketing Cloud email bodies, subject lines, preheaders, SMS, push notifications, or Cloud Pages — including Lookup/LookupRows data retrieval, IF/ELSEIF conditional blocks, FOR loops over rowsets, and inline personalization. NOT for Server-Side JavaScript (SSJS), REST API calls from content, SQL Query Activities, or Journey Builder configuration.
einstein-discovery-development
Use this skill when integrating Einstein Discovery predictions into Salesforce apps, automating bulk scoring jobs, deploying stories as prediction definitions, managing models via API, or querying prediction history. Trigger keywords: Einstein Discovery, smartdatadiscovery, predict endpoint, bulk scoring job, model refresh job, prediction definition, story deployment, regression prediction, multiclass prediction, CRM Analytics ML. NOT for CRM Analytics dashboard design, TCRM dataset management, Einstein Prediction Builder binary classification (which requires no CRM Analytics license), or Einstein Next Best Action recommendation strategies.
saql-query-development
Use this skill when writing, debugging, or optimizing SAQL queries in CRM Analytics — covering pipeline syntax, aggregation, windowing functions (rank, dense_rank, moving_average), cogroup joins, rollup subtotals, piggyback queries, and REST API execution. NOT for SOQL, standard Salesforce reports, SQL databases, or any non-CRM Analytics query language.
remote-site-settings
Use when configuring Remote Site Settings to allow Apex callouts to external URLs, or when distinguishing Remote Site Settings from CSP Trusted Sites for Lightning component resource loading. NOT for Named Credentials (use named-credential-configuration).