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

# Domain Routing

> Run multiple apps from a single tinykit instance

tinykit supports **domain-based routing**—point multiple domains to one server, and each domain serves a different app.

```
recipes.yourserver.com     → Recipe app
blog.yourserver.com        → Blog app
calculator.yourserver.com  → Calculator app
crm.yourserver.com         → CRM app
```

All apps share the same builder dashboard. One deployment, unlimited apps.

***

## How It Works

When a request arrives, tinykit:

1. Extracts the domain from the request
2. Looks up the project with that domain in Pocketbase
3. Serves the production HTML for that project

```
Request: recipes.yourserver.com/
         │
         ▼
Domain lookup: "recipes.yourserver.com"
         │
         ▼
Find project with matching domain
         │
         ▼
Serve project as static file (compiled HTML)
```

***

## URL Structure

For any domain pointing to your tinykit server:

| URL                    | What It Shows                           |
| ---------------------- | --------------------------------------- |
| `/`                    | Production app for this domain          |
| `/tinykit`             | Redirects to builder for this domain    |
| `/tinykit/studio`      | Builder for this domain's app           |
| `/tinykit/dashboard`   | List of ALL apps (same on every domain) |
| `/tinykit/studio?id=X` | Edit a specific app by ID               |

<Info>
  The dashboard shows all apps regardless of which domain you access it from. Domains only affect which app is served at the root URL (`/`).
</Info>

***

## Setting Up Multiple Domains

<Steps>
  <Step title="Deploy tinykit">
    Deploy to Railway or your preferred host. Note your server's IP address or hostname.
  </Step>

  <Step title="Configure DNS">
    Point your domains to your tinykit server:

    ```
    recipes.yourserver.com    A    → 123.45.67.89
    blog.yourserver.com       A    → 123.45.67.89
    calculator.yourserver.com A    → 123.45.67.89
    ```

    Or use CNAME records if your host provides a hostname:

    ```
    recipes.yourserver.com    CNAME → your-app.railway.app
    ```
  </Step>

  <Step title="Create apps">
    Visit each domain. If no app exists for that domain, you'll be redirected to create one:

    ```
    Visit: recipes.yourserver.com
    Redirect to: /tinykit/new?domain=recipes.yourserver.com
    ```

    Build your app, and it's immediately live at that domain.
  </Step>

  <Step title="Configure SSL (if needed)">
    Railway and most platforms handle SSL automatically. For self-hosted setups, use a reverse proxy like Caddy or nginx with Let's Encrypt.
  </Step>
</Steps>

***

## Managing Apps

### From the Dashboard

Visit `/tinykit/dashboard` from any domain to see all your apps:

* Click an app to edit it
* See each app's domain
* Create new apps

### From Any Domain

Access the builder for the current domain:

```
recipes.yourserver.com/tinykit
```

Or jump directly to a specific app by ID:

```
recipes.yourserver.com/tinykit/studio?id=abc123
```

***

## Domain Normalization

tinykit normalizes domains for matching:

* Removes port numbers (`:5173`, `:3000`)
* Removes `www.` prefix
* Converts to lowercase

So these all resolve to the same project:

```
recipes.yourserver.com
www.recipes.yourserver.com
RECIPES.yourserver.com
recipes.yourserver.com:443
```

***

## Unknown Domains

When someone visits a domain that doesn't have a project:

```
newapp.yourserver.com/
         │
         ▼
    No project found for "newapp.yourserver.com"
         │
         ▼
    Redirect to: /tinykit/new?domain=newapp.yourserver.com
```

The new project page shows: "Creating app for newapp.yourserver.com"

***

## Example Setup

### Scenario: Agency with Multiple Clients

```
# Your clients' domains
client-a.com     → Portfolio site
client-b.com     → Booking system
client-c.com     → Product catalog

# Your internal tools (subdomain)
admin.youragency.com → Internal dashboard
crm.youragency.com   → Client CRM
```

All running on one \$5/month Railway instance.

### Scenario: Personal Projects

```
# Different subdomains of your domain
recipes.mydomain.com    → Recipe collection
bookmarks.mydomain.com  → Bookmark manager
notes.mydomain.com      → Note-taking app
```

***

## Local Development

During local development, tinykit uses `localhost` as the domain. All apps are accessible via the dashboard at `/tinykit/dashboard`.

To test domain routing locally:

1. Add entries to your hosts file:
   ```
   127.0.0.1 recipes.local
   127.0.0.1 blog.local
   ```

2. Visit `recipes.local:5173` and `blog.local:5173`

3. Each will resolve to its respective project

***

## Deployment Considerations

### Railway

Railway provides a single URL (e.g., `your-app.railway.app`). To use custom domains:

1. Go to your Railway project settings
2. Add custom domains
3. Configure DNS as instructed
4. SSL is automatic

### Self-Hosted

For VPS deployments, use a reverse proxy:

<Tabs>
  <Tab title="Caddy (Recommended)">
    Caddy handles SSL automatically:

    ```
    recipes.yourserver.com {
      reverse_proxy localhost:5173
    }

    blog.yourserver.com {
      reverse_proxy localhost:5173
    }
    ```
  </Tab>

  <Tab title="nginx">
    ```nginx theme={null}
    server {
      listen 443 ssl;
      server_name recipes.yourserver.com blog.yourserver.com;

      ssl_certificate /path/to/cert.pem;
      ssl_certificate_key /path/to/key.pem;

      location / {
        proxy_pass http://localhost:5173;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
      }
    }
    ```
  </Tab>
</Tabs>

***

## Limitations

<Warning>
  Keep in mind:
</Warning>

* **Shared database**: All apps share the same Pocketbase instance. Collection names should be unique across apps, or use prefixes (e.g., `recipes_items`, `blog_posts`).

* **Shared authentication**: Pocketbase auth is shared. A user logged in on one domain is logged into all domains on that server.

* **Single server**: All apps run on the same server. High-traffic apps might need dedicated hosting.

***

## FAQ

<AccordionGroup>
  <Accordion title="Can I move an app to a different domain?">
    Yes. Edit the project in the dashboard and change its domain field. The app will immediately be served at the new domain.
  </Accordion>

  <Accordion title="What happens if two projects have the same domain?">
    The first matching project is served. Avoid duplicate domains—each project should have a unique domain.
  </Accordion>

  <Accordion title="Can I have an app with no domain?">
    Yes. Apps without domains are only accessible via the dashboard using their ID (`/tinykit/studio?id=X`).
  </Accordion>

  <Accordion title="Do subdomains work?">
    Yes. `app.example.com` and `other.example.com` are treated as different domains.
  </Accordion>
</AccordionGroup>
