Skip to content

Content Platform

This example is for teams building a content-heavy product surface: editorial pages, docs, media assets, search, and hybrid SSR or SSG delivery. It shows how Slingshot’s content, rendering, and runtime packages fit together instead of documenting them as separate islands.

Source-backed example app: examples/content-platform/

  • content and community features backed by the same platform
  • uploaded assets plus image-aware delivery
  • search over content records
  • SSR for request-time pages and SSG for pre-rendered routes
  • worker-friendly hosting with KV-backed ISR
  • registry-backed search sync and realtime delivery policy
Terminal window
bun add @lastshotlabs/slingshot \
@lastshotlabs/slingshot-assets \
@lastshotlabs/slingshot-auth \
@lastshotlabs/slingshot-community \
@lastshotlabs/slingshot-deep-links \
@lastshotlabs/slingshot-notifications \
@lastshotlabs/slingshot-permissions \
@lastshotlabs/slingshot-search \
@lastshotlabs/slingshot-ssg \
@lastshotlabs/slingshot-ssr \
@lastshotlabs/slingshot-runtime-edge
app.config.ts
import { defineApp } from '@lastshotlabs/slingshot';
import { createAssetsPackage } from '@lastshotlabs/slingshot-assets';
import { createAuthPlugin } from '@lastshotlabs/slingshot-auth';
import { createCommunityPackage } from '@lastshotlabs/slingshot-community';
import { createDeepLinksPlugin } from '@lastshotlabs/slingshot-deep-links';
import { createNotificationsPackage } from '@lastshotlabs/slingshot-notifications';
import { createPermissionsPackage } from '@lastshotlabs/slingshot-permissions';
import { createSearchPackage } from '@lastshotlabs/slingshot-search';
import { createSsrPackage, type SlingshotSsrRenderer } from '@lastshotlabs/slingshot-ssr';
import { edgeRuntime } from '@lastshotlabs/slingshot-runtime-edge';
import { createKvIsrCache, type KvNamespace } from '@lastshotlabs/slingshot-runtime-edge/kv';
declare const renderer: SlingshotSsrRenderer;
declare const ISR_CACHE: KvNamespace;
export default defineApp({
runtime: edgeRuntime({
fileStore: async (_path: string) => null,
}),
port: 3000,
security: { signing: { secret: process.env.JWT_SECRET! } },
plugins: [
createAuthPlugin({
auth: { roles: ['user', 'editor', 'admin'], defaultRole: 'user' },
db: { auth: 'memory', sessions: 'memory', oauthState: 'memory' },
}),
createDeepLinksPlugin({
fallbackBaseUrl: 'https://content.example.com',
fallbackRedirects: {
'/open/*': '/articles/:id',
},
}),
],
packages: [
createNotificationsPackage({
dispatcher: { enabled: false, intervalMs: 30_000, maxPerTick: 500 },
}),
createPermissionsPackage(),
createCommunityPackage({ containerCreation: 'admin' }),
createAssetsPackage({
storage: { adapter: 'memory' },
presignedUrls: true,
image: { allowedOrigins: ['assets.example.com'] },
}),
createSearchPackage({
providers: {
default: { provider: 'db-native' },
},
}),
createSsrPackage({
renderer,
serverRoutesDir: `${import.meta.dir}/server/routes`,
assetsManifest: `${import.meta.dir}/dist/client/.vite/manifest.json`,
staticDir: `${import.meta.dir}/dist/static`,
draftModeSecret: process.env.DRAFT_MODE_SECRET!,
isr: { adapter: createKvIsrCache(ISR_CACHE) },
}),
],
});
CapabilityPackage path
Authenticated editorial and admin surfaceslingshot-auth
Permission evaluation for community workflowsslingshot-permissions
Notification runtime for community activityslingshot-notifications
Community discussion alongside contentslingshot-community
Asset metadata, uploads, and image-aware servingslingshot-assets
Search over content recordsslingshot-search
Request-time page rendering, metadata, draft mode, and ISRslingshot-ssr
Build-time pre-rendering for stable routesslingshot-ssg
Mobile and browser entry routingslingshot-deep-links
Worker-host deployment and KV ISRruntime-edge
  • Use SSR for pages that depend on auth state, draft mode, or frequently changing data.
  • Use SSG for routes that can be generated ahead of time from stable content.
  • Use ISR when a page is mostly static but still needs cheap background revalidation.
  • Use runtime-edge when the deployment target is a worker host and you want bundled file reads plus shared ISR invalidation.
  • editorial pages rendered through slingshot-ssr
  • pre-generated landing pages and docs pages emitted by slingshot-ssg
  • uploads and media served through slingshot-assets
  • search endpoints powering site-wide discovery
  • entity-driven indexing and sync policy owned by the shared event registry
  • optional community discussion layered into article or docs pages