Skip to content

API Reference

Complete reference for all classes, functions, and types in the Aether Sites SDK.

Main SDK class for visual editor integration.

import { AetherSDK } from '@aether-official/sites-sdk';
const sdk = new AetherSDK(config);
new AetherSDK(config: AetherSDKConfig)

Parameters:

  • config - SDK configuration object

Example:

const sdk = new AetherSDK({
siteId: 'site-123',
organizationId: 'org-456',
editorOrigin: 'https://app.aether.com',
debug: true,
});

Subscribe to SDK events.

sdk.on(event: string, handler: Function): void

Events:

  • 'ready' - SDK initialized successfully
  • 'content:updated' - Content field updated
  • 'error' - Error occurred

Example:

sdk.on('ready', () => {
console.log('SDK ready!');
});
sdk.on('content:updated', (event) => {
console.log('Updated:', event.fieldPath, event.newValue);
});

Unsubscribe from events.

sdk.off(event: string, handler?: Function): void

Get current SDK state.

sdk.getState(): SDKState

Returns: Current state including connection status, history, etc.

Clean up and destroy SDK instance.

sdk.destroy(): void

Client-side content management with caching.

import { createContentManager } from '@aether-official/sites-sdk';
const content = createContentManager(config);

Fetch a section with caching.

async getSection(
id: string,
options?: { skipCache?: boolean }
): Promise<Section>

Example:

const section = await content.getSection('hero-123');
const fresh = await content.getSection('hero-123', { skipCache: true });

Fetch a page with all sections.

async getPage(
slug: string,
options?: { skipCache?: boolean }
): Promise<Page>

Update section data.

async updateSection(
id: string,
data: Record<string, any>
): Promise<Section>

Example:

await content.updateSection('hero-123', {
'hero.title': 'New Title',
'hero.subtitle': 'New Subtitle',
});

Low-level API client.

import { AetherAPIClient } from '@aether-official/sites-sdk';
const client = new AetherAPIClient(config);
async getSection(id: string): Promise<Section>
async getPage(slug: string): Promise<Page>
async updateSection(
id: string,
data: Record<string, any>
): Promise<UpdateSectionResponse>

Server-side section fetching.

import { fetchSection } from '@aether-official/sites-sdk';
const section = await fetchSection(
sectionId: string,
config: AetherSDKConfig
): Promise<Section>

Example:

const section = await fetchSection('hero-123', {
apiUrl: process.env.AETHER_API_URL,
apiToken: process.env.AETHER_API_TOKEN,
});

Server-side page fetching.

import { fetchPage } from '@aether-official/sites-sdk';
const page = await fetchPage(
slug: string,
config: AetherSDKConfig
): Promise<Page>

Fetch section at build time in Astro.

import { getAetherSection } from '@aether-official/sites-sdk/astro';
const section = await getAetherSection(
id: string,
config: AetherContentConfig
): Promise<Section>

Fetch page at build time.

import { getAetherPage } from '@aether-official/sites-sdk/astro';
const page = await getAetherPage(
slug: string,
config: AetherContentConfig
): Promise<Page>

Extract config from Astro environment.

import { getConfig } from '@aether-official/sites-sdk/astro';
const config = getConfig(env: Record<string, any>): AetherContentConfig

Example:

---
const config = getConfig(import.meta.env);
---

Get nested field value.

import { getField } from '@aether-official/sites-sdk/content';
const value = getField(
section: Section,
path: string
): any

Example:

const title = getField(section, 'hero.title');
const ctaText = getField(section, 'hero.cta.text');

Check if field exists.

import { hasField } from '@aether-official/sites-sdk/content';
const exists = hasField(
section: Section,
path: string
): boolean

Get array field with type safety.

import { getArrayField } from '@aether-official/sites-sdk/astro';
const items = getArrayField(
section: Section,
path: string
): any[] | undefined

Example:

const members = getArrayField(section, 'team.members');
members?.forEach(member => {
console.log(member.name);
});

SDK configuration interface.

interface AetherSDKConfig {
/** Unique site identifier */
siteId: string;
/** Organization identifier */
organizationId: string;
/** Editor origin URL for postMessage security */
editorOrigin: string;
/** Enable debug logging */
debug?: boolean;
/** Custom editable selector */
editableSelector?: string;
/** Auto-initialize on DOM ready */
autoInit?: boolean;
}

Content fetching configuration.

interface AetherContentConfig {
/** API URL */
apiUrl: string;
/** API authentication token */
apiToken: string;
/** Site identifier */
siteId?: string;
/** Organization identifier */
organizationId?: string;
}

Content section interface.

interface Section {
/** Section ID */
id: string;
/** Template ID (optional) */
templateId: string | null;
/** Section content data */
data: Record<string, any>;
/** Metadata */
metadata: {
updatedAt: string;
createdAt?: string;
};
}

Example:

const section: Section = {
id: 'hero-123',
templateId: null,
data: {
hero: {
title: 'Welcome',
subtitle: 'Description',
},
},
metadata: {
updatedAt: '2024-01-15T10:30:00Z',
},
};

Page with sections.

interface Page {
/** Page ID */
id: string;
/** URL slug */
slug: string;
/** Page title */
title: string;
/** Ordered sections */
sections: Section[];
/** Metadata */
metadata: {
updatedAt: string;
createdAt?: string;
};
}

Editable content field.

interface ContentField {
/** Field identifier */
id: string;
/** Section ID */
sectionId: string;
/** Field path (dot notation) */
fieldPath: string;
/** Field type */
fieldType: ContentFieldType;
/** Current value */
currentValue: any;
/** DOM element */
element?: HTMLElement;
/** Display label */
label?: string;
}
type ContentFieldType =
| 'text'
| 'textarea'
| 'image'
| 'repeater'
| 'rich-text';

type SDKEventType =
| 'ready'
| 'content:updated'
| 'error';
interface SDKEvent {
type: SDKEventType;
data?: any;
error?: Error;
}

API error class.

class AetherAPIError extends Error {
status: number;
statusText: string;
url: string;
}

Usage:

import { fetchSection, AetherAPIError } from '@aether-official/sites-sdk';
try {
const section = await fetchSection('hero-123', config);
} catch (error) {
if (error instanceof AetherAPIError) {
console.error('API Error:', error.status, error.message);
if (error.status === 404) {
// Section not found
} else if (error.status === 401) {
// Authentication failed
}
}
}

export const SDK_VERSION: string;

Current SDK version.


  • PUBLIC_AETHER_SITE_ID - Your site identifier
  • PUBLIC_AETHER_ORG_ID - Your organization identifier
  • PUBLIC_AETHER_EDITOR_URL - Editor URL (e.g., https://app.aether.com)
  • AETHER_API_URL - API endpoint (default: https://app.aether.com/api/trpc)
  • AETHER_API_TOKEN - API authentication token
  • AETHER_DEBUG - Enable debug logging

---
import { getAetherSection, getConfig, getArrayField } from '@aether-official/sites-sdk/astro';
const config = getConfig(import.meta.env);
const hero = await getAetherSection('hero-123', config);
const team = await getAetherSection('team-456', config);
const members = getArrayField(team, 'team.members') || [];
---
<!DOCTYPE html>
<html>
<head>
<title>{hero.data.hero.title}</title>
</head>
<body>
<!-- Hero -->
<section data-aether-section={hero.id}>
<h1 data-aether-field="hero.title">
{hero.data.hero.title}
</h1>
</section>
<!-- Team -->
<section data-aether-section={team.id}>
<div data-aether-repeater="team.members">
{members.map((member, i) => (
<div data-aether-repeater-item={i}>
<h3 data-aether-field={`team.members.${i}.name`}>
{member.name}
</h3>
</div>
))}
</div>
</section>
<!-- SDK -->
<script>
import { AetherSDK } from '@aether-official/sites-sdk';
const params = new URLSearchParams(window.location.search);
if (params.get('aether-editor') === 'true') {
new AetherSDK({
siteId: import.meta.env.PUBLIC_AETHER_SITE_ID,
organizationId: import.meta.env.PUBLIC_AETHER_ORG_ID,
editorOrigin: import.meta.env.PUBLIC_AETHER_EDITOR_URL,
});
}
</script>
</body>
</html>

Breaking changes:

  • getContent() renamed to getSection()
  • ContentClient renamed to ContentManager
  • Config now requires editorOrigin instead of editorUrl
// Old (1.x)
const content = await getContent('hero-123');
const client = new ContentClient(config);
// New (2.x)
const content = await getSection('hero-123');
const manager = createContentManager(config);