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

# Astro

> Build an Astro Site and deploy its static output to Liteshop.

Liteshop hosts the static files an [Astro](https://astro.build) build produces. Astro builds static HTML by default, so you only need to change how it names page files.

## Before you begin

* Install [Node.js](https://nodejs.org) 22 or later.
* Sign in to the [Liteshop dashboard](https://app.liteshop.me).

## Create the app

```sh theme={null}
npm create astro@latest my-site -- --template minimal --install --no-git --yes
cd my-site
```

Set `astro.config.mjs` to build one HTML file per page:

```js theme={null}
// @ts-check
import { defineConfig } from "astro/config";

export default defineConfig({
  build: { format: "file" },
  trailingSlash: "never",
});
```

[Routing](#routing) explains why.

## Add the manifest

Astro copies everything in `public/` to the root of the build, so put `liteshop.json` there:

```json theme={null}
{
  "$schema": "https://docs.liteshop.me/schemas/site-v0.1.json",
  "specVersion": "0.1",
  "site": {
    "name": "My Site",
    "defaultLocale": "en",
    "supportedLocales": ["en"],
    "timezone": "Europe/Paris"
  },
  "frontend": {
    "entry": "index.html"
  },
  "capabilities": {
    "forms": [
      {
        "id": "contact",
        "name": { "en": "Contact" },
        "fields": [
          { "id": "email", "type": "email", "label": { "en": "Email" }, "required": true },
          { "id": "message", "type": "textarea", "label": { "en": "Message" }, "required": true }
        ]
      }
    ]
  }
}
```

Leave `capabilities` as `{}` if the Site has no Form. The [Site Bundle reference](https://docs.liteshop.me/reference/site-bundle.md) lists every field.

## Add the SDK

Install the Liteshop SDK:

```sh theme={null}
npm install @liteshop.ai/sdk
```

Import `liteshop` from it wherever the Site uses Forms, bookings or the catalogue. It calls the Site's own Liteshop endpoints and includes its TypeScript types.

To try Forms with `npm run dev`, add the Liteshop plugin to `astro.config.mjs`:

```js theme={null}
// @ts-check
import { defineConfig } from "astro/config";
import { liteshop } from "@liteshop.ai/sdk/vite";

export default defineConfig({
  build: { format: "file" },
  trailingSlash: "never",
  vite: { plugins: [liteshop()] },
});
```

On the dev server, the plugin answers the SDK from `liteshop.json`: Form submissions are checked and printed in the terminal, the catalogue lists every item as available, and nothing is saved or sent to Liteshop.

## Submit a Form

Put the form in a component such as `src/components/Contact.astro`, with a normal `<script>`. Import the SDK and pass the Form ID as a literal string. Liteshop reads `liteshop.forms.submit("contact", ...)` from your built JavaScript to check that every declared Form has a handler.

```astro theme={null}
<form id="contact-form">
  <label>Email <input name="email" type="email" required /></label>
  <label>Message <textarea name="message" required></textarea></label>
  <button type="submit">Send</button>
  <p id="contact-status" role="status"></p>
</form>

<script>
  import { liteshop } from "@liteshop.ai/sdk";

  const form = document.querySelector<HTMLFormElement>("#contact-form")!;
  const status = document.querySelector("#contact-status")!;

  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    const data = new FormData(form);
    try {
      await liteshop.forms.submit("contact", {
        email: String(data.get("email")),
        message: String(data.get("message")),
      });
      form.reset();
      status.textContent = "Thanks, your message was sent.";
    } catch {
      status.textContent = "Your message could not be sent. Try again.";
    }
  });
</script>
```

Use it in a page, for example `src/pages/index.astro`:

```astro theme={null}
---
import Contact from "../components/Contact.astro";
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Home</title>
  </head>
  <body>
    <h1>Contact us</h1>
    <Contact />
  </body>
</html>
```

Astro bundles the script into a file, or inlines it when it is small. Both work: Liteshop allows each inline script by its hash. Don't add `method="post"` or an `action` to the form. See the [Forms reference](https://docs.liteshop.me/reference/forms.md) for field types and the anti-spam field.

## Build and package the Site

```sh theme={null}
npm run build
cd dist
zip -r ../site.zip .
```

The ZIP must have `index.html` and `liteshop.json` at its root, which zipping the contents of `dist` gives you.

## Upload the Site

To publish a new Site:

1. In the [Liteshop dashboard](https://app.liteshop.me), click **Website** > **Upload files**.
2. Enter the Site name and subdomain, and select `site.zip`.
3. Click **Check and publish**.

To update a Site, open **Website settings** (the gear button on the **Website** page), and upload the new ZIP file in **Upload an update**. An update's `liteshop.json` must name the live version in `baseDeployment`. If the value is missing or out of date, validation fails, and its repair message gives the exact value to set in `public/liteshop.json`. For details, see [Publish and manage a Site](https://docs.liteshop.me/develop/deploy.md).

## Routing

Liteshop serves `/about` from `about.html`, and from `about/index.html` by redirecting to `/about/`. Astro's default `build.format` is `"directory"`, which builds `src/pages/about.astro` as `about/index.html`, so every visit to `/about` costs a redirect. With `build.format: "file"` Astro builds `about.html`, and `/about` is served directly. `trailingSlash: "never"` makes the dev server match. Link to pages without a trailing slash, such as `<a href="/about">`.

## What runs on Liteshop

Liteshop hosts static output only: no on-demand rendering, server endpoints, actions or adapters. Every page must be prerendered, so dynamic routes need `getStaticPaths()`. The Site's security policy blocks scripts, styles and network requests to other origins, frames, workers and `eval`. Validation warns when your build appears to use one of those features, and fails on external scripts and frames. A default Astro build has no warnings.

## Dashboard edits

Site Owners can edit catalogue items, collections, and stock in the dashboard, which publishes a new Deployment from your files without rebuilding your app. Read the catalogue in the browser with `liteshop.catalogue.list()`. Don't import `liteshop.json` or render catalogue items at build time; otherwise, dashboard edits don't appear on the Site until you rebuild and upload it again. See the [Catalogue reference](https://docs.liteshop.me/reference/catalogue.md).


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