Webflow Exporter logo
Webflow → Astro

Migrate Webflow to Astro

Astro is the most natural target for a Webflow exit: content collections read Markdown from a folder, the front-matter is type-checked against a Zod schema, and pages ship with zero JS by default. Webflow Export produces content in exactly that shape — your collections drop into src/content/ with the right keys and asset paths.
Export for AstroNo paid Webflow plan required

Why Astro fits Webflow exits

  1. Content collections expect Markdown in a folder. Our exporter outputs exactly that — one folder per collection, one .md per item, front-matter typed.
  2. Zero JS by default.Pages render faster than the Webflow original because there's no runtime CSS injection and no Webflow JS bundle.
  3. Sane TypeScript story. Each collection gets a Zod schema; references and dates are real values, not strings.
  4. Islands when you need them.Drop in a React or Svelte component for the one interactive widget you can't avoid — without making the whole site a SPA.

Setup, end to end

  1. 1

    Export from Webflow

    Use Webflow Export. You'll get the static pages plus one folder per CMS collection containing .md, .mdx, and .json files with normalized front-matter.

  2. 2

    Create an Astro project

    npm create astro@latest — pick the minimal starter. Add Tailwind or your styling choice via astro add.

  3. 3

    Drop in the content folders

    Move each collection folder from the export into src/content/. Move the export's assets/ into public/assets/ (or under src/assets/if you want Astro's asset pipeline to process them).

  4. 4

    Define the content collection schema

    Add src/content/config.ts:

    import { defineCollection, z } from "astro:content";
    
    const blogPosts = defineCollection({
      type: "content",
      schema: z.object({
        title: z.string(),
        slug: z.string(),
        date: z.coerce.date(),
        cover: z.string().optional(),
        excerpt: z.string().optional(),
      }),
    });
    
    export const collections = { "blog-posts": blogPosts };

    The keys match the front-matter the exporter generates — no renaming needed.

  5. 5

    Build a route

    Add src/pages/blog/[slug].astro:

    ---
    import { getCollection } from "astro:content";
    
    export async function getStaticPaths() {
      const posts = await getCollection("blog-posts");
      return posts.map((p) => ({ params: { slug: p.slug }, props: { post: p } }));
    }
    
    const { post } = Astro.props;
    const { Content } = await post.render();
    ---
    <article>
      <h1>{post.data.title}</h1>
      <time>{post.data.date.toDateString()}</time>
      <Content />
    </article>
  6. 6

    Rebuild the static marketing pages

    Pages without CMS data go under src/pages/ as .astrofiles. Use the exported HTML as a layout and copy reference; you'll usually clean up class names and factor out shared chunks into components.

  7. 7

    Deploy

    npm run build, drop dist/on any static host. Astro's output is ~50–80% smaller than the equivalent Webflow page once Webflow's runtime CSS and JS are gone.

Webflow CMS fields → Astro schema

Webflow fieldFront-matter shapeZod type
Plain textstringz.string()
Rich textContent body (rendered via Content)— (not in schema)
ImageRelative path stringz.string()
DateISO stringz.coerce.date()
ReferenceSlug stringreference("other-collection")
Multi-referenceArray of slugsz.array(reference("other-collection"))
SwitchBooleanz.boolean()
OptionStringz.enum([...])

FAQ — Webflow to Astro

Does the rich-text body keep its formatting in Astro?

Yes. The exporter converts Webflow rich text to clean Markdown, and Astro's Content component renders it with proper heading levels, lists, code blocks, blockquotes, and inline images.

Can I use MDX instead of plain Markdown in Astro?

Yes — install @astrojs/mdx, then rename the exported .md files to .mdx (or use the .mdx copies the exporter already produces). You can drop Astro components into the content body for callouts, embeds, and anything else.

How do references between collections work?

Use Astro's reference()helper in your schema. The exporter outputs reference fields as the referenced item's slug, which matches the file name in the other collection — so Astro can resolve them at build time.

What about images in CMS rich text?

Every image in a rich-text field is downloaded into the assets folder and the Markdown is rewritten to point at the relative path. In Astro, you can either keep them in /public/assets/ for direct serving, or move into src/assets/and let Astro's image pipeline process them.

Is this faster than the Webflow original?

Almost always. Zero JS by default, no runtime CSS injection, and Astro's image pipeline produces aggressive responsive variants. LCP improvements of 30–60% are typical.

Ready to try it?

Paste a Webflow API token, scan the site for free, and only pay when you download. Every page, asset, and CMS item is included.

Related

Last updated May 19, 2026