Skip to content

Custom components

Save layers once and reuse them on any page with every copy linked, or write a component in code with its own properties and events.

4 min readPublished 7 November 2026

Plans
Every plan, including Free
Where
Insert, then Custom Components
On this page
  1. Two ways to make one
  2. Save layers as a custom component
  3. Work with linked copies
  4. Make a copy independent
  5. Write a component in code
  6. Current limits

Two ways to make one

A custom component is a part of your app that you save once and reuse. Both kinds sit in Components, under Custom Components beside Built-in, and both are labelled as custom components on the canvas, in Layers and in the Inspector.

CompareFrom selected layersWritten in code
Start fromLayers you have designed on the canvasA React Native file in Code
Edit itOn the canvas, through any copyIn its file; every copy follows
Each copy keepsIts own size, outside space, alignment in its parent, name, visibility and lockIts own property values, size, placement and event actions
Good forCards, headers and repeated sectionsGames, charts and custom interactions

Save layers as a custom component

  1. Select one component, or several neighbouring layers in the same container.
  2. In the Inspector, open the Custom component section and choose Create custom component. You can also right-click the selection, or choose Create custom component in Custom Components and then Use selected layers.
  3. Enter a Component name and choose Create custom component.

Your selection becomes the first copy, in the same place. Several layers are wrapped in a new container that takes the parent's direction and spacing, so check any layout that depended on the parent's space. Locked layers, layers already inside a custom component and a code component on its own cannot be saved, and for a group you select its contents instead. The Inspector explains what is in the way.

Work with linked copies

Add more copies from Custom Components: click a card, or drag it onto a page. Each card says how many copies are in your app, and duplicating a copy gives you another linked one. Edit any copy and the change reaches every copy in the same step, whether it is text, colours, layout, inside space, or layers you add, move or remove inside it.

Select a layer inside a copy and the Inspector says it is Inside a custom component, with Select component to reach the copy itself. Edit component on a card opens a copy on the canvas, adding one if none is placed yet.

Actions inside a copy are shared too. A button that opens a page opens it from every copy, and a button that opens a popup inside the component opens that copy's own popup.

Make a copy independent

When one copy needs its own content or structure, select it and choose Make this copy independent. Its layers stay on the page as ordinary components and stop receiving shared updates, while the other copies stay linked. If the copy or a layer around it is locked, turn that lock off first.

Deleting a copy never deletes the component. Rename changes the component's name in the library, and the remove button on its card works once no copies are left in your app. Code components have no independent mode; each copy already keeps its own property values.

Write a component in code

Choose New component file in Custom Components, or Start with code after Create custom component. In Code, New project file offers Custom component too, and Use as custom component in the toolbar registers an existing file whose default export is a React Native component. The dialog has three tabs:

Component
Its Component name, an optional description and its Code file: a new file with a guided template, or an existing project file.
Properties
The controls each copy gets in the Inspector. Each has a Display name, an exact Name in code, a Control (Text, Long text, Number, Toggle, Colour or Choice), a default and an Inspector category.
Events
Callbacks such as onFinish that your code calls when something happens. Each copy chooses the result in its Actions tab: open a page, go back or open a website.

Create and open file checks that the project compiles, adds the component to the page and opens its file beside the preview. Your code receives the values as props, typed by the generated @appsanic/custom module; a TypeScript field alone does not create a control. Component settings in the Code toolbar changes properties and events later.

A registered component file
import { Pressable, Text } from "react-native";
import type { CustomComponentProps } from "@appsanic/custom";
import { theme } from "@appsanic/design";

// Registered with a Text property "label" and an event "onFinish".
// A starter file already names its own component ID here.
type Props = CustomComponentProps<"custom-1a2b3c4d">;

export default function FinishButton(props: Props) {
  return (
    <Pressable
      accessibilityRole="button"
      onPress={() => props.onFinish()}
      style={{ backgroundColor: theme.primary, borderRadius: 12, padding: 14 }}
    >
      <Text style={{ color: theme.onPrimary }}>{props.label}</Text>
    </Pressable>
  );
}

On the canvas each copy renders on its own, as one selectable item; taps, navigation and bindings run in Preview. On a paid plan, Sanic AI can register properties and connect them to your code for you.

Current limits

  • Saved designs have no variants, and a linked copy cannot override its text or style. Make the copy independent instead.
  • A saved design cannot contain a copy of another saved design; make the inner copy independent first. Code components can sit inside one.
  • A layer cannot be moved into or out of a copy without making the copy independent.
  • A project holds up to 100 saved designs and 100 code components, and a code component has up to 64 properties and 64 events.
  • A page or asset used inside a saved design cannot be deleted while the design exists, even with no copies placed.
  • Removing a code component checks that the rest of the project still compiles. Its file stays unless you tick Also delete source file.
  • Libraries a code component imports must support React Native, and Expo Go cannot load extra native modules.