# Code Structure

SSE encourages you to separate code into TypeScript classes that can be easily managed and organized.

These include;

* Site-level classes, which contain site-wide functionality
* Page-level classes, which contain page-specific functionality
* Component-level classes, which contain code specific to a reusable component

## Base Classes (Recommended)

**New in v2.0:** SSE provides base classes with automatic context detection. This is the recommended approach for pages and components.

### PageBase for Pages

Pages extend `PageBase` to get automatic Webflow context detection:

* **onPrepare()** - Synchronous setup during `<head>` load
* **onLoad()** - Asynchronous execution after DOM ready
* **this.pageInfo** - Automatic Webflow context (pageId, siteId, collectionId, itemSlug, etc.)

### ComponentBase for Components

Components extend `ComponentBase` to get automatic element context:

* **onPrepare()** - Synchronous setup during `<head>` load
* **onLoad()** - Asynchronous execution after DOM ready
* **this.element** - The HTMLElement the component is bound to
* **this.context** - Component metadata (name, id, dataAttributes)

## The IModule Interface (Advanced)

For advanced use cases, you can still implement the `IModule` interface directly. This gives you full control but requires manual context detection.

### Legacy Lifecycle Methods

When implementing `IModule` directly:

* **setup()** - Runs synchronously at the end of `</head>`
* **exec()** - Runs asynchronously after DOM is loaded

Let's look at how these approaches work in practice.

## Site Class

Exists at `/src/site.ts`

The Site class still uses `IModule` directly since it doesn't need automatic context detection:

```typescript
import { IModule, Page } from "@sygnal/sse-core";

export class Site implements IModule {

  constructor() {
  }

  setup() {
    // Site-wide setup code
  }

  exec() {
    console.log("Site loaded.")
  }

}
```

## Page Classes (Recommended Approach)

**New in v2.0:** Pages should extend `PageBase` for automatic Webflow context detection.

All Page classes are stored in `/src/pages` folder. By convention, Pages end in `Page`.

Here's an example using the recommended `PageBase` approach:

```typescript
import { PageBase, page } from "@sygnal/sse-core";

@page('/')
export class HomePage extends PageBase {

  protected onPrepare(): void {
    // Synchronous setup - access automatic context
    console.log('Page ID:', this.pageInfo.pageId);
    console.log('Collection:', this.pageInfo.collectionId);
  }

  protected async onLoad(): Promise<void {
    // Asynchronous execution after DOM ready
    console.log('Item Slug:', this.pageInfo.itemSlug);
    console.log("Home page loaded.");
  }

}
```

### Available Page Context

When using `PageBase`, you automatically get access to:

* `this.pageInfo.path` - Current page path
* `this.pageInfo.pageId` - Webflow page ID
* `this.pageInfo.siteId` - Webflow site ID
* `this.pageInfo.collectionId` - CMS collection ID (if applicable)
* `this.pageInfo.itemId` - CMS item ID (if applicable)
* `this.pageInfo.itemSlug` - CMS item slug (if applicable)
* `this.pageInfo.queryParams` - URL query parameters
* `this.pageInfo.hash` - URL hash
* `this.pageInfo.domain` - Webflow domain
* `this.pageInfo.lang` - Page language

## Component Classes (Recommended Approach)

**New in v2.0:** Components should extend `ComponentBase` for automatic element context.

All Component classes are stored in `/src/components` folder. By convention, Components end in `Component`.

Here's an example using the recommended `ComponentBase` approach:

```typescript
import { ComponentBase, component, PageBase } from "@sygnal/sse-core";

@component('navigation')
export class NavigationComponent extends ComponentBase {

  protected onPrepare(): void {
    // Access element and context automatically
    console.log('Component:', this.context.name);
    console.log('Element:', this.element);
  }

  protected async onLoad(): Promise<void> {
    // Access current page info if needed
    const page = PageBase.getCurrentPage();
    if (page) {
      const info = page.getPageInfo();
      console.log('On page:', info.pageId);
    }

    // Add event listeners
    this.element.addEventListener('click', () => {
      console.log('Navigation clicked');
    });
  }

}
```

Use the public `getPageInfo()` accessor (the `pageInfo` property is protected) whenever a component needs Webflow page context.

### Available Component Context

When using `ComponentBase`, you automatically get access to:

* `this.element` - The HTMLElement the component is bound to
* `this.context.name` - Component name from `data-component` attribute
* `this.context.id` - Component ID from `data-component-id` attribute
* `this.context.dataAttributes` - All data-\* attributes on the element

## Usage Notes

Execution order:

* Site code executes on all pages first (both `setup()` and `exec()`)
* Page code executes second (both `onPrepare()` and `onLoad()`)
* Component code executes last (both `onPrepare()` and `onLoad()`)

{% hint style="success" %}
Components are fully implemented in v2.0 with automatic discovery and initialization!
{% endhint %}
