Astro

Sync your Astro codebase to Versoly using our CLI.

In this guide, you’ll learn about the required files for syncing, customising the Versoly config file based on your project layout and how to sync your Versoly website to your Astro codebase.

Prerequisites

  • A Versoly account
  • A codebase with Astro, Tailwind and ideally Typescript
  • Node.js 20.0.0 or higher

Project Structure

├── public/ # Static assets (e.g., images, fonts)
│ ├── images/ # Versoly will sync images here
├── src/
│ ├── components/ # Reusable components (e.g., buttons, headers)
│ ├── layouts/ # Layouts for different page types
│ ├── pages/ # Your page content (in .astro or .mdx)
│ ├── styles/ # Global CSS or Tailwind styles
│   ├── global.css # Used for Tailwind CSS
│   ├── versoly.css # Auto generated CSS from Versoly for Versoly UI such as .btn, .col
│   ├── versoly-forms.css # Extended Tailwind forms plugin to work properly with v4 + Versoly UI
├── package.json # Project scripts and dependencies
└── astro.config.mjs # Astro configuration
└── versoly.config.mjs # Versoly cli/sync configuration
└── .env # Includes VERSOLY_ACCESS_TOKEN

If you want to see an example of an Astro codebase check out the github repository.

Required files

versoly.config.mjs

// @ts-check
import { defineConfig } from "@versoly/cli";

export default defineConfig({
  token: process.env.VERSOLY_ACCESS_TOKEN || "",
  siteId: "your-site-id",

  // rootDir: "./monorepo-packages/ui",
  // srcDir: "./src",
  // publicDir: "./public",
  // pagesDir: "./pages",
  // componentsDir: "./components",
  // pluginsDir: "./scripts/plugins",
  // "exclude": ["public/robots.txt"],
});

.env

VERSOLY_ACCESS_TOKEN=YOUR_API_KEY

tsconfig.json

{
  // ...
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
}

src/styles/global.css

@import "tailwindcss";
@plugin "@tailwindcss/typography";

/* Tailwind v4 does not play well with component/utility layers, fix is to inline vs import, also enables use of primary */
/* https://github.com/tailwindlabs/tailwindcss-forms/issues/162#issuecomment-3587908303 */
@import "./versoly-forms.css";
@import "./versoly.css";

src/components/BaseHead.astro

---
import "@/styles/global.css";
import type { PageLayoutMetaProps } from "@/utils/metaTagsToString";
import { metaTagsToString } from "@/utils/metaTagsToString";

type Props = PageLayoutMetaProps;

const { site, obj } = Astro.props;
const metaTagsAsString = metaTagsToString({ site, obj });
---

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="sitemap" href="/sitemap-index.xml" />
<meta name="generator" content={Astro.generator} />
<Fragment set:html={metaTagsAsString} />

src/layouts/PageLayout.astro

---
import { SITE_CONFIG as site } from "@/config/site.mjs";
import BaseHead from "@/components/BaseHead.astro";
import type { PageMetaProps } from "@/utils/metaTagsToString";

type Props = PageMetaProps;

const metaData: PageMetaProps & { url: string } = {
  title: Astro.props.title || site.title,
  description: Astro.props.description || site.description,
  lang: Astro.props.lang || site.lang || "en",
  favicon: Astro.props.favicon || site.favicon,
  metaTags: Astro.props.metaTags,
  url: Astro.url.href || "",
  bodyProperties: Astro.props.bodyProperties || {},
};

const { head, scripts, bodyProperties } = Astro.props;
const { lang } = metaData;
---

<!doctype html>
<html lang={lang}>
  <head>
    <BaseHead site={site} obj={metaData} />
    <Fragment set:html={site.head} />
    <Fragment set:html={head} />
  </head>
  <body {...bodyProperties}>
    <script>
      import "@/scripts/plugins/data-attrs.js";
    </script>

    <slot />

    <Fragment set:html={site.scripts} />
    <Fragment set:html={scripts} />
    <script>
      import "versoly-ui";
    </script>
  </body>
</html>

Syncing

Once you have added the required files you can then run Versoly CLI sync tool

pnpm dlx @versoly/cli sync

Troubleshooting

If you're using tailwind forms add /src/styles/versoly-forms.css, Tailwind V4 has issues with the new layer feature.

© 2026 Versoly

Powered proudly by Versoly