Landing Page
The portal's home page is a React file: apitogo/portal/landing/LandingPage.tsx, named by
portal.landing in apitogo.config.json. apitogo add portal writes a starter one (or
apitogo create --template full). It composes section components from
@lukoweb/apitogo-module-landing inside a LandingShell:
| Component | Purpose |
|---|---|
HeroSection | Headline, description, CTAs and code examples |
TrustSection | Logos or social proof |
FeaturesSection | Feature grid |
StepsSection | Numbered "how it works" steps |
ApiShowcaseSection | Grid or method + path list of your API |
PlansPreviewSection | Short plan comparison linking to /pricing |
PricingCtaSection | Closing call to action |
Edit the file directly to add, remove or reorder sections. Remove portal.landing from the config
to have no home page: / then opens the first docs page. The footer is a file of its own (see
Footer).
API showcase
ApiShowcaseSection renders the items you pass it. The scaffold ships with a static sample
list:
Code
Each item accepts name, path, and optionally method, summary, icon and latency.
Live APIs
Instead of maintaining the list by hand, you can load your API's real operations. Your dev portal
backend syncs the gateway actions of your project (every operation discovered from the OpenAPI
spec you deployed) and serves them publicly at GET /api/v1/actions. The useGatewayActions() hook
fetches that list; you decide what to show and pass the result to ApiShowcaseSection.
Code
Filters
useGatewayActions() accepts server-side filters. All filters are combined:
| Option | Type | Description |
|---|---|---|
inPlan | boolean | Only actions included in at least one active plan |
plan | string | Only actions included in the plan with this SKU |
isPublic | boolean | Only actions callable without an API key (or only not) |
method | string | HTTP method, e.g. GET |
pathPrefix | string | Path prefix, e.g. /v1/orders |
limit | number | Maximum number of actions (server cap: 500) |
enabled | boolean | Set to false to skip the request |
Anything else — sorting, renaming, grouping, picking a hand-curated subset — is up to you in plain TypeScript before you build the items.
Each action has this shape:
Code
Actions only carry the method and path. Use the summaries argument of toApiShowcaseItems() (or
your own mapping) to add human-friendly names.
Always keep a fallback
The hook runs in the browser only, so the prerendered HTML never contains a stale list. data is
undefined:
- while the request is loading,
- if the request fails,
- in preview and demo mode, or when no dev portal backend URL is configured (for example in
npm run devbefore your portal is provisioned).
ApiShowcaseSection renders nothing for an empty list, so pass a static fallback as shown above.
What becomes public
GET /api/v1/actions is anonymous: every operation in the OpenAPI spec deployed to your gateway
is listable, including ones you may not document in the portal. Use inPlan: true to limit the
list to operations your plans actually sell, and remove internal operations from the spec you deploy
to the gateway if they must not be discoverable.
Freshness and limits
- The backend syncs actions at startup and on the plan sync interval (15 minutes by default). A new release shows up after the next sync.
- Responses are cacheable for 5 minutes (
Cache-Control: public, max-age=300). - The endpoint is rate limited per client IP (60 requests per minute).
Troubleshooting
- The list is always the fallback: the project has no plans backend yet. Add
plansto the config and runapitogo deploy. - CORS errors: the backend only allows the portal's configured frontend URL. Serving the site from another domain requires adding it to the backend's allowed origins.
- Empty list on a new portal: the portal is not activated yet, or the gateway has no release. Deploy your backend, then wait for the next sync.
Plans preview
PlansPreviewSection shows the same plans as /pricing. The scaffold loads them with the
usePlansPreview hook from the billing plugin, so you only maintain plans in one place,
apitogo/plans.json:
Code
In a live portal the plans come from your dev portal backend (GET /api/v1/plans); in local
preview, and while the live catalog loads, they come from apitogo/plans.json. Each card shows the
plan's displayName, price and billing period, and its first two feature lines (features, or
lines derived from limits). The highlighted card matches the "Popular" plan on /pricing.
To write the cards by hand instead, pass a static array of { name, price, unit, blurb, featured }
objects to plans.