@ossy/app
v0.15.13
Published
Server-side rendering runtime and build tooling for Ossy apps. Use with `@ossy/cli` for the convention-based setup (`npx @ossy/cli dev`).
Readme
@ossy/app
Server-side rendering runtime and build tooling for Ossy apps. Use with @ossy/cli for the convention-based setup (npx @ossy/cli dev).
For custom setups (Next.js, Vite, etc.), use @ossy/connected-components directly — see the root README.
Setup
Create *.page.jsx files in src/:
// src/home.page.jsx
import React from 'react'
export default () => <h1>Welcome</h1>Each file becomes a route: home.page.jsx → /, about.page.jsx → /about. Optionally export metadata for custom id/path or multi-language:
export const metadata = { path: { en: '/about', sv: '/om' } }
export default () => <h1>About</h1>For a single-file setup, use src/pages.jsx (legacy).
Split pages are merged into build/.ossy/pages.generated.jsx (next to other build output) during dev / build.
List modules: ['@your/npm-package', ...] in src/config.js to pull in every *.page.js, *.page.jsx, *.page.ts, and *.page.tsx file under each package’s src/ tree (any subfolder). Deprecated: pagesModules / pagesModule — still read for now, with a deprecation warning.
Optional src/page-shell.jsx (or .js): default export your site layout component. usePageShell() from @ossy/connected-components wraps module pages in that shell so packages do not import site paths.
Note: @ossy/connected-components is slated for retirement; its responsibilities (app shell, routing wrapper, usePageShell, etc.) should move into @ossy/app or smaller focused packages over time. See that package’s README.
Add src/config.js for workspace and theme:
import { CloudLight } from '@ossy/themes'
export default {
workspaceId: 'your-workspace-id',
theme: CloudLight, // or 'light' | 'dark' | CloudDark
apiUrl: 'https://api.ossy.se/api/v0', // optional
}Config is loaded at build time and merged with request-time settings (e.g. user theme preference from cookies). The server passes workspaceId, apiUrl, and theme to the App component.
Run npx @ossy/cli dev or npx @ossy/cli build.
API routes
Define HTTP handlers as an array of { id, path, handle(req, res) } objects (same shape the server passes to @ossy/router).
Split files (recommended): add any number of *.api.js (or .api.mjs / .api.cjs) files under src/ (nested dirs allowed). Each file’s default export is either one route object or an array of routes. They are merged: src/api.js first (if present), then each *.api.js in lexicographic file path order.
Legacy single file: src/api.js default export is still supported. If it exists, its routes are merged first, then every *.api.js.
At build/dev time this becomes build/.ossy/api.generated.js (under your --destination / build output, typically gitignored with the rest of build/) whenever you have src/api.js and/or any *.api.js, so the Rollup entry stays stable when you add or remove split files.
Override: pass --api-source ./path/to/file.js to use a single file and skip discovery.
Example src/health.api.js:
export default {
id: 'health',
path: '/api/health',
handle(req, res) {
res.json({ status: 'ok' })
},
}Example src/api.js (optional aggregate or empty []):
export default [
{
id: 'users',
path: '/api/users',
handle(req, res) {
res.json({ users: [] })
},
},
]API routes are matched before the app is rendered. The router supports dynamic segments (e.g. path: '/api/users/:id'); extract params from req.originalUrl if needed. Use paths that don't conflict with /@ossy/* (reserved for the internal proxy).
Background worker tasks (*.task.js)
For long-running job processors (separate from the SSR server), use npx @ossy/cli build --worker in a package that only needs the worker. It uses the same Rollup + Babel pipeline as ossy build, discovers *.task.js (and .task.mjs / .task.cjs) under src/ (or --pages <dir>), and writes build/.ossy/tasks.generated.js when needed—same idea as *.api.js and the generated API bundle.
Optional legacy aggregate: src/tasks.js default export is merged first, then each *.task.js in path order.
Each task file’s default export is { type, handler } where type matches the platform job type string, and handler is async ({ sdk, job }) => { ... } (see @ossy/worker for examples).
Override: --task-source ./path/to/tasks.js skips discovery and uses a single file.
Output: build/worker.js. Run with node build/worker.js (after import 'dotenv/config' via the entry). Set OSSY_WORKSPACE_ID, OSSY_API_URL, and OSSY_API_TOKEN as before.
Port configuration
By default, the server listens on port 3000.
- Environment variable: set
PORT - CLI argument: pass
--port <number>(or-p <number>) when running the built server file
Examples:
# env var
PORT=4000 node build/server.js
# CLI arg
node build/server.js --port 4000
node build/server.js -p 4000