> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cskn.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# App data

> The data the host injects into window.cskn before your code runs.

Whatever serves your page (the cskn web worker, or a native shell's offline copy of your bundle) writes a small object into `window.cskn` before your code runs. It tells your app which app it is, whose page it is on, and who is signed in.

```html theme={null}
<script>
  window.cskn = {
    isUserPage: true,
    user: { username: "ada" },
    app: { id: "6912…", slug: "blog", name: "Blog", version: "1.0.4", status: "active", isPublic: true }
  };
</script>
```

## Reading it

```tsx theme={null}
import { getAppData, getAppInfo, getAppUser, getAppAuth, isUserPage } from '@cskn/sdk';

getAppData();   // the whole object, or null when nothing was injected
getAppInfo();   // { id, slug, name?, version, status, isPublic } | null
getAppUser();   // { username } of the page owner on a user page, else null
getAppAuth();   // the signed-in browser user, or null
isUserPage();   // boolean
```

<Note>
  The host only ever **adds** to `window.cskn`, and a native shell attaches its bridge to the same object. Neither is guaranteed to arrive first, so never assign `window.cskn = …` in your own code; spread into it instead (see [Local development](#local-development)).
</Note>

## Fields

<ResponseField name="isUserPage" type="boolean">
  `true` on a creator's profile (`<username>.cskn.my/<slug>`), `false` on the app's own host.
</ResponseField>

<ResponseField name="user" type="{ username: string } | null">
  The owner of the profile being viewed. Only set on a user page.
</ResponseField>

<ResponseField name="app" type="object" required>
  <Expandable title="properties">
    <ResponseField name="id" type="string">The app's id.</ResponseField>
    <ResponseField name="slug" type="string">The slug this bundle is served as. The platform's per-app API routes key on it.</ResponseField>
    <ResponseField name="name" type="string">The app's catalog name. Not every app has one.</ResponseField>
    <ResponseField name="version" type="string">The deployed version.</ResponseField>
    <ResponseField name="status" type="string">`"active"` when the app is live.</ResponseField>
    <ResponseField name="isPublic" type="boolean">Whether the app is listed publicly.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="auth" type="object | null">
  The user signed in to this browser: `{ sub, name, username, picture, email, email_verified }`. `null` for a visitor, and inside a native shell, where identity comes over the bridge instead.
</ResponseField>

<ResponseField name="mountPath" type="string">
  Where your routes are mounted: `""` on the app's own host, `"/<slug>"` on a user page. Read it through [`appBasename()`](/sdk/urls#routing).
</ResponseField>

<ResponseField name="theme" type="object | null">
  The theme the page owner selected, resolved before first paint. Consumed by [`useThemeSelection`](/sdk/themes).
</ResponseField>

<ResponseField name="push" type="{ vapidPublicKey: string | null; serviceWorker: string }">
  What a browser needs to subscribe to Web Push. Consumed by [Web Push](/sdk/native/web-push).
</ResponseField>

## Common patterns

**Show the profile owner's data on a user page, and the signed-in user's data otherwise:**

```tsx theme={null}
import { getAppUser, isUserPage, useAppData } from '@cskn/sdk';

function Posts() {
  const owner = isUserPage() ? getAppUser()?.username : undefined;
  const { data } = useAppData<{ posts: Post[] }>({ appId: 'blog', username: owner });
  return <PostList posts={data?.data.posts ?? []} />;
}
```

**Gate the app on its status:**

```tsx theme={null}
const app = getAppInfo();
if (app?.status !== 'active') return <Unavailable />;
```

## Local development

`pnpm dev` has no host to inject anything. Fill in a stand-in when nothing is there, and spread rather than assign so a bridge that a shell attached is kept:

```tsx main.tsx theme={null}
if (import.meta.env.DEV && !window.cskn?.app) {
  window.cskn = {
    ...window.cskn,
    isUserPage: import.meta.env.VITE_IS_USER_PAGE === 'true',
    user: import.meta.env.VITE_IS_USER_PAGE === 'true' ? { username: 'devuser' } : null,
    app: { id: 'dev', slug: 'my-app', version: '0.1.0', status: 'active', isPublic: true },
    auth: null,
  };
}
```

Run with `VITE_IS_USER_PAGE=true pnpm dev` to preview the user page.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.