# How a Deco Site Uses the Framework

Reference based on `deco-sites/osklenbr`, a production VTEX storefront using Fresh/Preact.

## Site Structure

```
osklenbr/
|-- deno.json              # Dependencies, tasks, import map
|-- fresh.config.ts        # Fresh + Deco plugin registration
|-- manifest.gen.ts        # Auto-generated manifest (site blocks)
|-- fresh.gen.ts           # Auto-generated Fresh manifest (routes + islands)
|-- runtime.ts             # Typed invoke client
|-- main.ts                # Production entry: start(manifest, config)
|-- dev.ts                 # Dev entry: tailwind build + dotenv + Fresh dev
|
|-- apps/                  # App registrations (site.ts, decohub.ts)
|-- sections/              # 117 UI sections (Preact components)
|-- islands/               # 99 interactive islands (Preact)
|-- loaders/               # 13 site-specific loaders
|-- actions/               # 4 site-specific actions
|-- routes/                # 2 routes (_app.tsx, proxy.ts)
|-- sdk/                   # Client-side utilities
|-- components/            # Shared Preact components
|-- static/                # Static assets
```

## Configuration

### deno.json

Key imports: `$fresh/` (Fresh 1.7.3), `@deco/deco` (1.174.2), `apps/` (deco-cx/apps 0.139.0), `$store/` and `site/` (self-reference).

Tasks: `start` (production via deco.cx/run), `dev` (generate + Fresh dev), `gen` (manifest generation).

JSX: `react-jsx` with `preact` import source.

### fresh.config.ts

```typescript
import { defineConfig } from "$fresh/server.ts";
import { plugins } from "deco/plugins/deco.ts";
import manifest from "./manifest.gen.ts";

export default defineConfig({
  plugins: plugins({ manifest, htmx: false }),
});
```

### runtime.ts

```typescript
import { proxy } from "@deco/deco/web";
import type { Manifest } from "./manifest.gen.ts";
import type { Manifest as VTEXManifest } from "apps/vtex/manifest.gen.ts";

export const invoke = proxy<Manifest & VTEXManifest>();
```

## App Registration (`apps/`)

### apps/site.ts

```typescript
import manifest, { Manifest } from "../manifest.gen.ts";
import { type App, type AppContext as AC } from "@deco/deco";
import commerce from "apps/commerce/mod.ts";
import std from "apps/compat/std/mod.ts";

export type AppContext = AC<ReturnType<typeof Site>>;

export default function Site(state: Props): App<
  Manifest, Props, [typeof std, ReturnType<typeof commerce>]
> {
  return {
    state,
    manifest,
    dependencies: [std(state), commerce(state)],
  };
}
```

Key pattern: site app bundles manifest + commerce dependencies. `AppContext` enables typed `ctx.invoke()`.

### apps/decohub.ts

```typescript
export { default, Preview } from "apps/decohub/mod.ts";
```

## Execution Flow

### Production
```
main.ts -> fresh.gen.ts + fresh.config.ts -> start(manifest, config)
  -> Fresh server starts
  -> Deco plugin initializes
  -> Loads DecofileProvider (CMS state)
  -> Installs apps (site -> commerce -> vtex)
  -> Registers all block resolvers
  -> Mounts routes + middleware
```

### Dev
```
dev.ts -> Build Tailwind -> Load .env -> Fresh dev server -> Generate manifest -> Hot reload
```

## Manifest System

### manifest.gen.ts (Deco)

Contains loaders (13), sections (117), actions (4), matchers (1), apps (2). Keys formatted as `site/loaders/...`, `site/sections/...`.

### fresh.gen.ts (Fresh)

Contains routes (2) and islands (99). Generated by Fresh from the Deco plugin.

## Loader/Action Patterns

### Site Loader

```typescript
import { AppContext } from "site/apps/site.ts";

export default async function loader(
  props: Props,
  _req: Request,
  ctx: AppContext,
): Promise<Store[]> {
  // fetch data, transform, return
}
```

### Invoking Other Apps

```typescript
export default async function loader(props: Props, _req: Request, ctx: AppContext) {
  const products = await ctx.invoke(
    "vtex/loaders/intelligentSearch/productListingPage.ts",
    { query: props.query, count: 12 },
  );
  return products;
}
```

## Routes

`_app.tsx` is the global layout. Page routes are NOT file-based; they come from the CMS admin decofile.

## Migration Patterns for TanStack

| Fresh/Deco Pattern | TanStack Equivalent |
|--------------------|---------------------|
| `manifest.gen.ts` | Explicit exports from `@decocms/apps-start` |
| `runtime.ts` invoke proxy | Direct function imports + React Query |
| Islands | Regular React components |
| Fresh `<Partial>` | TanStack Router navigation |
| `useSection()` partial render | React state + React Query invalidation |
| `ctx.invoke("key", props)` | Direct function call: `loaderFn(props)` |
| `AppContext` | `configureVtex()` + env vars |
| Deco plugin | TanStack Start entry + `@decocms/start` |
| DecofileProvider | Admin API from `@decocms/start` |
| `@preact/signals` | `@tanstack/react-store` or React state |
| `Deno.env.get()` | `process.env` or `import.meta.env` |
