Skip to content

Quickstart

This chapter is the fastest reproducible path to a real JSKIT app.

The base flow below gives you:

  • personal workspaces
  • users
  • console
  • MySQL
  • Supabase auth
  • one admin assistant configured from console

It also shows the first page-extension moves most apps need:

  • add two workspace settings pages
  • make one of them the default landing page
  • add a page to the admin cog
  • add a normal left-menu page
  • inspect placement destinations and understand why some links are inferred automatically

Step 1: Create the app

Set these values first:

bash
OPENAI_API_KEY=...
SUPABASE_URL=...
SUPABASE_KEY=...
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=testapp
DB_USER=...
DB_PASSWORD=...

Before continuing, make sure the MySQL database already exists and that the chosen DB_USER / DB_PASSWORD can connect to it. If the database does not exist yet, create it first or use a local MySQL account with enough privileges to create it before the runtime install step.

Then run the exact sequence below:

bash
npx @jskit-ai/create-app testapp --tenancy-mode personal
cd testapp
npm install

npx jskit add package auth-provider-supabase-core \
  --auth-supabase-url "$SUPABASE_URL" \
  --auth-supabase-publishable-key "$SUPABASE_KEY" \
  --app-public-url "http://localhost:5173"

npx jskit add bundle auth-base

npx jskit add package database-runtime-mysql \
  --db-host "$DB_HOST" \
  --db-port "$DB_PORT" \
  --db-name "$DB_NAME" \
  --db-user "$DB_USER" \
  --db-password "$DB_PASSWORD"

npx jskit add package users-web
npx jskit add package console-web
npx jskit add package workspaces-core
npx jskit add package workspaces-web

npx jskit generate assistant setup \
  --surface admin \
  --settings-surface console \
  --config-scope global \
  --ai-provider openai \
  --ai-api-key "$OPENAI_API_KEY"

npx jskit generate assistant page \
  w/[workspaceSlug]/admin/assistant/index.vue \
  --name "Assistant"

npx jskit generate assistant settings-page \
  console/settings/admin-assistant/index.vue \
  --surface admin \
  --name "Admin Assistant"

npm install
npm run db:migrate

At this point you have:

  • a workspace-enabled app with tenancyMode = "personal"
  • an admin assistant at /w/[workspaceSlug]/admin/assistant
  • an assistant settings page at /console/settings/admin-assistant

Step 2: Add two workspace settings pages

Generate two child pages under the workspace settings host:

bash
npx jskit generate ui-generator page \
  w/[workspaceSlug]/admin/workspace/settings/billing/index.vue \
  --name "Billing"

npx jskit generate ui-generator page \
  w/[workspaceSlug]/admin/workspace/settings/branding/index.vue \
  --name "Branding"

These commands create:

  • src/pages/w/[workspaceSlug]/admin/workspace/settings/billing/index.vue
  • src/pages/w/[workspaceSlug]/admin/workspace/settings/branding/index.vue

They also append matching menu entries into src/placement.js.

Step 3: Make one settings page the default

Best practice is to make the default child explicit.

Edit:

text
src/pages/w/[workspaceSlug]/admin/workspace/settings/index.vue

and replace its contents with:

vue
<script setup>
import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";

definePage({
  redirect: redirectToChild("billing")
});
</script>

That makes /w/[workspaceSlug]/admin/workspace/settings land on /w/[workspaceSlug]/admin/workspace/settings/billing.

Use this explicit redirect pattern instead of trying to infer the default child from placement order or “the first generated page”.

Step 4: Add a page to the admin cog

First list the available placement destinations:

bash
npx jskit list-placements

In a workspace-enabled app, that output includes the semantic admin.tools-menu placement.

Then generate the page:

bash
npx jskit generate ui-generator page \
  w/[workspaceSlug]/admin/catalogue/index.vue \
  --name "Catalogue" \
  --link-placement admin.tools-menu

--link-placement is necessary here because this is just a normal admin page. It is not a child page under a local route host that already owns a nested outlet.

Step 5: Add a normal left-menu page

Generate a normal admin page without an explicit placement:

bash
npx jskit generate ui-generator page \
  w/[workspaceSlug]/admin/reports/index.vue \
  --name "Reports"

Because this page is not under a more specific local host, JSKIT falls back to the app's default shell menu outlet. In practice, that means a normal left-menu entry.

Step 6: Understand the placement "magic"

The workspace settings pages in Step 2 auto-linked into the settings menu for two reasons:

  1. The parent host already exposes a concrete outlet:
vue
<ShellOutlet target="admin-settings:primary-menu" />
  1. Your generated pages live under that host route:
text
w/[workspaceSlug]/admin/workspace/settings/...

So JSKIT can infer both:

  • the semantic placement target: page.section-nav
  • the placement owner: admin-settings

The renderer comes from src/placementTopology.js, where page.section-nav maps to the concrete admin-settings:primary-menu outlet for each layout class.

That is why the simple settings-page commands do not need --link-placement.

The admin cog example is different. w/[workspaceSlug]/admin/catalogue/index.vue is just a normal admin page, so there is no local nested host to infer. That is why you must pass --link-placement admin.tools-menu there.

If you want a little more context than the raw destination list, this is also useful:

bash
npx jskit show @jskit-ai/workspaces-web --details

That output shows both the workspace-owned placement outlets and the default entries already targeting them.

JSKIT documentation