Export a Framer site as a static site with Vite

Export a Framer site as static files: convert it to a Vite and React project that prerenders every page into dist/ for any static host, with no server.

Published
Reading time
5 min
Deframer cover: “Static files, no server.” Beside it, a list of Framer site, Vite build, dist/ and Static host with dist/ selected
On this page10 sections

Framer can't export static files, but you can turn a published Framer site into one. Convert it with Deframer to the Vite target and you get a Vite and React project in TypeScript; npm run build prerenders every page into dist/ as HTML, and that folder is the whole site. Upload it to Netlify, Cloudflare Pages, Vercel, GitHub Pages or an S3 bucket behind a CDN, with no server to run. Unlike a saved-page snapshot, it is a project you can keep editing and rebuild.

Deframer is an independent tool and is not affiliated with, endorsed or sponsored by Framer. Downloading the code is for your own site or one whose owner allows it.

Static snapshot or static build?

There are two ways to end up with static files from a Framer site, and they are very different.

Saved HTML snapshot

Vite project

How you get it

Save the rendered pages with a crawler or "Save page as"

Convert the site, then npm run build

What you edit

Minified HTML and Framer's bundled scripts

React components, CSS modules, JSON content

Depends on Framer's scripts

Usually, yes

No: a small kit in the project replaces the runtime

CMS

Frozen in the HTML

JSON files you edit, then rebuild

Forms

Post to Framer, which stops when the plan ends

Post to a form service you choose

Redirects

Lost

Carried over for common static hosts

Framer to HTML or Next.js goes deeper on snapshots. This post is about the second column.

How do you export a Framer site with Vite?

  1. Sign in to Deframer and paste the published address.
  2. Choose Vite in the framework menu.
  3. Pick the asset option. For a fully self-contained static site, choose Assets in the project so images, fonts and videos are copied into public/. The default keeps them on Framer's CDN, which makes the download smaller.
  4. Convert (free, up to 10 minutes) and review the notices.
  5. Verify ownership with the one-line meta tag and download. A verified download is 1 credit, or free with the lifetime deal.
  6. Build:
sh
npm install
npm run build      # vite build, then scripts/prerender.ts
npm run preview    # serves dist/ the way a static host does

The build needs Node.js 22.18 or later on your machine or CI. Production needs nothing but a static host.

What does dist/ look like?

The prerender script writes every page as a flat file at its URL:

Code
dist/
  index.html          /
  about.html          /about
  blog/
    first-post.html   /blog/first-post
  404.html            the 404 page
  assets/             scripts and stylesheets
  _redirects          for Netlify and Cloudflare Pages

Each page is styled before its scripts run, then hydrates in the browser. After that, links open the next page in the same document with React Router, so the layout template two pages share stays mounted.

Netlify, Cloudflare Pages and GitHub Pages serve about.html at /about without extra settings. The project's vercel.json turns on clean URLs for Vercel.

Redirects on a static host

Framer sites often carry redirects from older URLs. The Vite project brings them as:

  • public/_redirects, read by Netlify and Cloudflare Pages;
  • vercel.json, read by Vercel;
  • for hosts with neither, such as GitHub Pages, a small page at each old URL that sends the browser on.

Search engines handle server redirects best, so prefer a host that reads _redirects or vercel.json if your old URLs have rankings worth keeping. See keeping SEO when moving off Framer.

Forms without a server

A static site has nowhere to post a form to, so each native form posts to a form service instead. Set VITE_FORM_ENDPOINT (or a form's own variable) to the service's URL when you build; Formspree and Basin are common choices. On Netlify, set it to netlify and Netlify Forms receives the submissions. Because the value is read at build time, set it in your host's build environment, not only on your laptop.

What a static site can't do

Being static has a few consequences worth knowing before you choose:

  • CMS items added later have no prerendered page until you rebuild. A new item renders in the browser from 404.html with a 404 status, so after editing the JSON, rebuild and redeploy. Adding items in Framer means converting again.
  • Split tests need a server to assign variants, so the static build ships each tested page's original version only.
  • Anything per request, such as sessions or personalized pages, needs a server. Pick Next.js, Astro or another server target for that.

Where to host it

Host

What to set

Netlify

Build npm run build, publish dist; _redirects works (guide)

Cloudflare Pages

Build npm run build, output dist (guide)

Vercel

Framework preset Vite, output dist; vercel.json is read

GitHub Pages

Deploy dist/ with Actions (guide)

S3 and CloudFront

Upload dist/ (guide)

Checks before you switch the domain

Run these against npm run preview locally, then again on the host's preview URL:

  1. Every page loads at its old URL. Use the README's route list, including CMS detail pages.
  2. The 404 page answers with a 404 status. curl -I https://your-preview-url/does-not-exist should show it.
  3. Redirects work. For each old URL in public/_redirects, curl -I should show a 301 or 308 to the right target on hosts that read the file.
  4. Forms reach the form service. Submit each form from the deployed preview, not just locally, because the endpoint is baked in at build time.
  5. Breakpoints and animations look right at about 1440, 768 and 390 pixels.
  6. Assets don't point at Framer if you chose "Assets in the project". Search dist/ for framerusercontent.com; with the default option, those references are expected.
  7. robots.txt and sitemap.xml name your production domain.

Updating the site

Edit content in src/cms/*.json, copy in src/views, or styles in src/styles, run npm run build, and deploy dist/ again. Most hosts do this automatically on every push once the repository is connected. If you keep designing in Framer and want the changes, convert again and merge; maintaining a converted site with Git shows how.

FAQ

Can Framer export a static HTML site?

No. Framer hosts sites itself and has no file export. A converter that reads the published site, such as Deframer's Vite target, is the way to get static files you can host anywhere.

Do animations still work in the static build?

Yes. Pages hydrate in the browser, and animations and interactions run on motion through the project's kit.

Do I need Node.js on the server?

No. Node.js 22.18 or later is only needed to build. The output in dist/ is plain files.

Is the static export good for SEO?

Every page is a full HTML document with its title, description and social image, and robots.txt and sitemap.xml come with the project. Use a host that applies _redirects or vercel.json so old URLs return real redirects.

How much does it cost?

Converting is free. A verified download uses 1 credit; packs start at $10, and the $397 lifetime deal makes verified downloads free. See pricing.

Keep reading

All posts
  • Deframer cover: “Lose the badge. Two real ways.” Beside it, two cards, Paid plan or Own code, with Own code selected

    Branding6 min read

    How to remove the "Made in Framer" badge

    The "Made in Framer" badge goes away on a paid Framer site plan. Here is how that works, why CSS tricks are a poor idea, and the no-badge route of owning code.

  • Deframer cover: “Host it free. Push to Pages.” Beside it, four tiles, Convert, Build, Actions and Pages, with Pages selected

    Hosting8 min read

    Host a Framer site on GitHub Pages

    Convert a Framer site to a static Vite project, build it, push it to GitHub and deploy with Actions. Also works on Netlify, Cloudflare Pages and S3.