Salesforce · · 14 min read

Design Attributes, Targeting, and Icons in LWC

How to make your LWC configurable and placeable — design attributes for admin configuration, targeting to control where components appear, and adding custom SVG icons to your components.

Part 87: Design Attributes, Targeting, and Icons in LWC

Back in Part 77, we walked through the XML metadata file that every Lightning Web Component requires. That post covered the fundamentals — the apiVersion, the isExposed flag, and the targets element that tells the platform where your component is allowed to live. We touched on design attributes and targets at a high level because you needed to understand what the XML file does before you could use it effectively. Now that you have built real components, wired them to Apex, handled exceptions, and styled them with CSS, it is time to go deeper into the three features that make your components truly production-ready: design attributes, targeting, and custom icons.

Here is the problem these features solve. You build a component that displays a list of records. It works perfectly on the Account record page in your dev org. But then a Salesforce admin wants to use that same component on the Contact page, with a different number of records displayed, and with a different title. Without design attributes, you would need to hardcode those values or create a separate component for every variation. Without proper targeting, the admin cannot even find your component in Lightning App Builder. And without a custom icon, your component sits in the component palette with a generic placeholder that looks like every other custom component. Design attributes, targeting, and icons are what turn a developer’s prototype into an admin-friendly, reusable tool.

This post covers:

  1. What are Design Attributes — Why they exist and what they give you.
  2. How to Setup Design Attributes for Your LWC — Step-by-step configuration.
  3. What is Targeting — How component placement works on the platform.
  4. How to Setup Targets for Your LWC — Controlling where your component appears.
  5. How to Setup an SVG Icon for Your LWC — Adding a custom icon to your component.
  6. Section Notes — Key takeaways and patterns to remember.

Let’s get into it.


What Are Design Attributes?

Design attributes are properties of your Lightning Web Component that Salesforce admins can configure directly in Lightning App Builder without touching any code. When an admin drags your component onto a page, the properties panel on the right side of App Builder displays your design attributes as form fields. The admin types in a value, saves the page, and your component receives that value at runtime.

Think of design attributes as the public API of your component, but for non-developers. A developer interacting with your component in code would pass values through HTML attributes or public properties. An admin interacting with your component in App Builder uses design attributes to achieve the same thing. The difference is that design attributes are defined in the XML metadata file and the platform handles the UI for setting them.

Without design attributes, every configurable value in your component would need to be hardcoded or fetched from some external source. That means every time someone wants a different heading, a different record count, or a different filter value, a developer has to make a code change and redeploy. Design attributes eliminate that bottleneck entirely.

Common use cases for design attributes include setting display titles, configuring the number of records to show, toggling visibility of sections, providing record type filters, setting default field values, and passing in record IDs or other contextual data. Essentially, anything that should be flexible across different pages or different users is a candidate for a design attribute.


How to Setup Design Attributes for Your LWC

Setting up design attributes requires changes in two files: the JavaScript controller and the XML metadata file. The JavaScript file defines the public property that will receive the value, and the XML file defines how that property appears in Lightning App Builder.

Step 1: Define the Public Property in JavaScript

In your component’s JavaScript file, you create a property decorated with @api. This makes the property public, meaning it can receive values from parent components and from the platform.

import { LightningElement, api } from 'lwc';

export default class RecordList extends LightningElement {
    @api cardTitle = 'Records';
    @api recordCount = 5;
    @api showHeader = true;
}

Each @api property here has a default value. If the admin does not set a value in App Builder, the component falls back to these defaults. The property names follow JavaScript camelCase convention — cardTitle, recordCount, showHeader.

Step 2: Use the Properties in Your Template

Your HTML template references these properties just like any other reactive property.

<template>
    <lightning-card title={cardTitle}>
        <template lwc:if={showHeader}>
            <p class="slds-p-horizontal_small">
                Displaying {recordCount} records
            </p>
        </template>
        <!-- Record list rendering here -->
    </lightning-card>
</template>

Nothing special is happening in the template. It simply reads the values that will be set either by defaults, by a parent component, or by an admin through App Builder.

Step 3: Configure the XML Metadata File

This is where design attributes come to life. In your .js-meta.xml file, you add a targetConfigs section that defines which properties are exposed in App Builder and how they appear.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>62.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage,lightning__AppPage,lightning__HomePage">
            <property name="cardTitle" type="String" label="Card Title"
                      description="The title displayed at the top of the card"
                      default="Records" />
            <property name="recordCount" type="Integer" label="Number of Records"
                      description="How many records to display"
                      default="5" min="1" max="50" />
            <property name="showHeader" type="Boolean" label="Show Header"
                      description="Toggle the header section on or off"
                      default="true" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

Let’s break down what is happening. The targetConfigs element wraps one or more targetConfig elements. Each targetConfig specifies which targets it applies to via the targets attribute. Inside, you define property elements that map directly to your @api properties in JavaScript.

Each property element supports several attributes:

  • name — Must match the JavaScript property name exactly, in camelCase.
  • type — The data type. Supported types include String, Integer, Boolean, Color, and Apex (for passing an Apex class name).
  • label — The human-readable label the admin sees in App Builder.
  • description — A help text that appears when the admin hovers over the field.
  • default — The default value shown in App Builder.
  • min and max — For Integer types, constrains the allowed range.
  • placeholder — Placeholder text for String inputs.
  • required — Whether the admin must provide a value.

Important Naming Convention

There is a naming detail that trips up many developers. In JavaScript, your property is camelCase: cardTitle. In the XML property element, the name attribute is also camelCase: name="cardTitle". But when you use the component in HTML markup from a parent component, the attribute becomes kebab-case: card-title. The platform handles this translation automatically for design attributes in App Builder, so you only need to worry about the camelCase name in the XML and JS files.

Different Configurations for Different Targets

You can define different design attributes for different targets. This is useful when a property only makes sense in certain contexts. For example, a record page component might need a related object field, while the same component on a home page would not.

<targetConfigs>
    <targetConfig targets="lightning__RecordPage">
        <property name="cardTitle" type="String" label="Card Title" default="Related Records" />
        <property name="relatedField" type="String" label="Related Field API Name" />
    </targetConfig>
    <targetConfig targets="lightning__HomePage">
        <property name="cardTitle" type="String" label="Card Title" default="My Records" />
    </targetConfig>
</targetConfigs>

Here, the relatedField property only appears when the component is placed on a record page. On the home page, the admin only sees the cardTitle property. This keeps the configuration clean and context-appropriate.


What Is Targeting?

Targeting is the mechanism that controls where your Lightning Web Component is allowed to appear within the Salesforce platform. When you define targets in your XML metadata file, you are telling the platform which surfaces your component supports. If you do not include a target, your component simply will not show up as an option in that context.

We introduced targets briefly in Part 77 when covering the XML file structure. The concept is straightforward: Salesforce has many different places where components can live — record pages, app pages, home pages, community pages, flow screens, utility bars, and more. Each of these surfaces has a corresponding target string. By listing targets in your XML file, you opt your component into those surfaces.

Targeting matters because not every component makes sense everywhere. A component that displays fields from a specific record obviously needs record context, so placing it on a home page without that context would cause errors. A flow screen component needs to communicate with the flow engine. A quick action component runs in a modal dialog. Each surface has its own requirements and behaviors, and targeting ensures your component only appears where it can function correctly.


How to Setup Targets for Your LWC

Targets are defined in the targets element of your .js-meta.xml file. Each target you want to support gets its own target child element.

Available Targets

Here are the most commonly used targets:

Target StringWhere It Appears
lightning__RecordPageRecord detail pages in Lightning Experience
lightning__AppPageCustom app pages built in App Builder
lightning__HomePageThe Lightning Experience home page
lightning__FlowScreenFlow screen components
lightning__UtilityBarThe utility bar at the bottom of the screen
lightning__RecordActionQuick actions on record pages
lightningCommunity__PageExperience Cloud (Community) pages
lightningCommunity__DefaultExperience Cloud with default wrapper
lightning__TabLightning page tabs
lightning__InboxOutlook and Gmail integrations

Basic Target Configuration

A typical component that should appear on record pages, app pages, and home pages uses this configuration:

<targets>
    <target>lightning__RecordPage</target>
    <target>lightning__AppPage</target>
    <target>lightning__HomePage</target>
</targets>

When you save this and deploy, your component will appear in the component palette of Lightning App Builder whenever you are editing one of those page types. If you are editing a record page, it shows up. If you are editing a flow screen, it does not, because lightning__FlowScreen is not in the list.

Targeting for Flow Screens

Flow screen components have a special consideration. When you target lightning__FlowScreen, you need to define your design attributes so that the flow builder can pass values into your component and receive values back.

<targets>
    <target>lightning__FlowScreen</target>
</targets>
<targetConfigs>
    <targetConfig targets="lightning__FlowScreen">
        <property name="inputLabel" type="String" label="Input Label"
                  role="inputOnly" />
        <property name="selectedValue" type="String" label="Selected Value"
                  role="outputOnly" />
    </targetConfig>
</targetConfigs>

The role attribute is specific to flow screen targets. Setting role="inputOnly" means the flow can pass a value into the component but the component does not send it back. Setting role="outputOnly" means the component sends a value back to the flow but the flow cannot set it. If you omit role, the property works in both directions.

Targeting for Experience Cloud

If you are building components for Experience Cloud sites, you will use lightningCommunity__Page and often pair it with lightningCommunity__Default. The difference is that lightningCommunity__Page gives your component full control over its rendering, while lightningCommunity__Default wraps it in a standard community component container.

<targets>
    <target>lightningCommunity__Page</target>
    <target>lightningCommunity__Default</target>
</targets>

Object-Specific Targeting

You can restrict your component to specific objects using the objects element inside targetConfig. This is useful when your component only makes sense on certain record types.

<targetConfigs>
    <targetConfig targets="lightning__RecordPage">
        <objects>
            <object>Account</object>
            <object>Contact</object>
            <object>Opportunity</object>
        </objects>
    </targetConfig>
</targetConfigs>

With this configuration, the component will only appear in App Builder when the admin is editing an Account, Contact, or Opportunity record page. It will not show up on Case, Lead, or any custom object pages. This prevents admins from accidentally placing the component somewhere it was not designed to work.


How to Setup an SVG Icon for Your LWC

When your component appears in the Lightning App Builder component palette, it displays an icon next to its name. By default, every custom LWC gets a generic gray icon that looks identical to every other custom component. If an admin is choosing from a palette that includes ten custom components, they all look the same and the only way to tell them apart is by reading the names. A custom icon solves this by giving your component a distinct visual identity.

Creating the SVG File

To add a custom icon, you create an SVG file inside your component’s folder. The file must be named the same as your component, with the .svg extension. If your component folder is recordList, the icon file is recordList.svg.

force-app/
  main/
    default/
      lwc/
        recordList/
          recordList.html
          recordList.js
          recordList.js-meta.xml
          recordList.svg

The SVG file should be a standard SVG document. Salesforce recommends keeping it simple — a 60x60 pixel viewBox with clean vector shapes. Here is an example:

<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 60 60">
    <rect width="60" height="60" rx="8" fill="#4C6EF5" />
    <rect x="10" y="14" width="40" height="4" rx="2" fill="#FFFFFF" />
    <rect x="10" y="24" width="32" height="4" rx="2" fill="#FFFFFF" opacity="0.8" />
    <rect x="10" y="34" width="36" height="4" rx="2" fill="#FFFFFF" opacity="0.8" />
    <rect x="10" y="44" width="28" height="4" rx="2" fill="#FFFFFF" opacity="0.6" />
</svg>

This creates a blue rounded rectangle with horizontal white lines — a simple visual that suggests a list of records. You can create your SVG in any vector editor like Figma, Illustrator, or even hand-code it. The key is keeping it simple enough to be recognizable at small sizes.

Guidelines for SVG Icons

There are a few rules to follow when creating your SVG icon:

  1. Keep the viewBox at 60x60. The platform scales it down, so start at this size for the best rendering.
  2. Use solid colors and simple shapes. Gradients and complex paths may not render well at small sizes.
  3. Do not use external resources. No linked images, no external CSS files, no embedded fonts. Everything must be inline.
  4. Test the icon at small sizes. App Builder displays it at roughly 20x20 pixels. If your icon is not recognizable at that size, simplify it.
  5. Use a background fill. Without a background, your icon will appear as floating shapes on the palette’s background, which looks inconsistent.

Deploying the Icon

The SVG file deploys along with the rest of your component files. When you run sf project deploy start or push via source tracking, Salesforce picks up the SVG file automatically. There is no additional configuration needed in the XML file. The platform recognizes the naming convention and associates the icon with your component.

After deploying, open Lightning App Builder and look for your component in the palette. You should see your custom icon instead of the generic placeholder. If the icon does not appear, double-check the file name matches the component name exactly and that the SVG is valid markup.


Section Notes

Design attributes, targeting, and icons are not glamorous features, but they are the difference between a component that only a developer can use and a component that an entire admin team can deploy and configure across the org.

Here is what to remember from this post:

  • Design attributes let admins configure your component in App Builder. Define @api properties in JavaScript and map them with property elements in the XML metadata file. Use types, labels, descriptions, and defaults to make the admin experience smooth.
  • Targeting controls where your component can appear. Always be intentional about which targets you include. Do not expose a component to every surface if it only works in one context. Use the objects element to restrict record page components to specific objects.
  • Custom SVG icons give your component a visual identity in the App Builder palette. Name the SVG file to match the component folder name, keep the design simple, and stick to a 60x60 viewBox.
  • Target configs can vary by target. You can show different design attributes on record pages versus home pages versus flow screens. Use this to keep the admin experience clean and context-appropriate.
  • The role attribute on properties is specific to flow screen targets and controls whether data flows into the component, out of the component, or both.
  • Always test in App Builder after deploying. Verify that your design attributes appear correctly, that the component shows up on the right page types, and that your icon renders at the small palette size.

These three features close the loop on making your Lightning Web Components truly platform-ready. In the next section, we will continue building on this foundation with more advanced component patterns. See you there.