Building Components

Build Custom Components

Create reusable UI components in React, Vue, or Svelte. Each component includes a schema file that defines which props are editable in the page builder. Your marketing team gets a visual editor to update content, while you maintain full control over design and behavior.

How Components Work

Component File

Your component code with props that accept content from the page builder.

Schema File

JSON that tells Oaysus which props are editable and how to render the editor UI.

Result

When you push components, Oaysus reads the schema and automatically generates form fields in the page builder. Marketing edits content visually, and your component renders it live.

Framework Examples

components/HeroBanner/index.tsx
1interface HeroBannerProps {
2  heading: string
3  subheading: string
4  buttonText: string
5  buttonLink: string
6  backgroundImage?: string
7  overlayOpacity?: number
8}
9
10export default function HeroBanner({
11  heading = 'Welcome to Our Site',
12  subheading = 'Build something amazing with Oaysus',
13  buttonText = 'Get Started',
14  buttonLink = '/',
15  backgroundImage,
16  overlayOpacity = 0.5
17}: HeroBannerProps) {
18  return (
19    <section
20      className="relative py-24 px-6 text-white"
21      style={{
22        backgroundImage: backgroundImage ? `url(${backgroundImage})` : undefined,
23        backgroundSize: 'cover',
24        backgroundPosition: 'center'
25      }}
26    >
27      {backgroundImage && (
28        <div
29          className="absolute inset-0 bg-black"
30          style={{ opacity: overlayOpacity }}
31        />
32      )}
33      <div className="relative max-w-4xl mx-auto text-center">
34        <h1 className="text-5xl font-bold mb-4">{heading}</h1>
35        <p className="text-xl mb-8 opacity-90">{subheading}</p>
36        <a
37          href={buttonLink}
38          className="inline-block bg-white text-gray-900 px-8 py-3 rounded-lg font-medium hover:bg-gray-100 transition-colors"
39        >
40          {buttonText}
41        </a>
42      </div>
43    </section>
44  )
45}
components/HeroBanner/schema.json
1{
2  "displayName": "Hero Banner",
3  "category": "marketing",
4  "props": {
5    "heading": {
6      "type": "string",
7      "label": "Heading",
8      "default": "Welcome to Our Site"
9    },
10    "subheading": {
11      "type": "string",
12      "label": "Subheading",
13      "default": "Build something amazing with Oaysus"
14    },
15    "buttonText": {
16      "type": "string",
17      "label": "Button Text",
18      "default": "Get Started"
19    },
20    "buttonLink": {
21      "type": "string",
22      "label": "Button Link",
23      "default": "/"
24    },
25    "backgroundImage": {
26      "type": "image",
27      "label": "Background Image"
28    },
29    "overlayOpacity": {
30      "type": "number",
31      "label": "Overlay Opacity",
32      "default": 0.5,
33      "min": 0,
34      "max": 1,
35      "step": 0.1
36    }
37  }
38}

Schema Field Types

string

Single line text

text

Multi-line text

number

Numeric value

boolean

True/false toggle

color

Hex color value

image

Image from media library

array

Repeatable list of items

select

Dropdown with options

Field Options

labelDisplay name shown in the editor. If omitted, the prop name is used.
defaultInitial value when the component is added to a page.
requiredIf true, the field must have a value before publishing.
optionsFor select type: array of { value, label } objects.
min / max / stepFor number type: constrain the input range.
itemSchemaFor array type: defines the shape of each item in the list.

Best Practices

TypeScriptDefine prop interfaces to catch type mismatches between your component and schema.

DefaultsComponents should render something meaningful even with default props.

ImagesHandle missing images with conditional rendering or fallback backgrounds.

TailwindUse Tailwind classes. Avoid custom CSS files that won't be loaded.

FocusOne component per concern. Don't build Swiss army knives.

Component Categories

Set the category field in your schema to organize components in the page builder:

marketing
content
navigation
footer
social-proof
ecommerce
forms
media