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.