figma.to.website docs
Last updated
What it is
figma.to.website is a Figma plugin that publishes your Figma design as a real, fast website — no code, no export step. What you draw is what visitors get: auto layout, components, variables and prototype interactions become HTML, CSS and a small runtime, served from a global CDN.
On top of the design, it adds what a site needs: Notion as a CMS, built-in forms, localization, dark mode, SEO settings, custom domains, redirects, analytics, custom code and password protection.
| Where | What you do there |
|---|---|
| Figma plugin | Pages, components, embeds, forms, CMS, settings, preview and publish |
| Web dashboard | Your sites, form submissions, users and plan |
| Published site | <name>.figweb.site, or your own domain
|
Guides
Step-by-step guides for each feature, with the layer names to use and screenshots.
- Start here Basics: how a Figma file becomes a website Each Figma section is a web page named by its URL path, and its frames are published as HTML and CSS, prototypes included.
- How to add links to a website made in Figma Figma text links and Navigate to or Open link interactions become real links, to your own pages by path or to any URL.
- How to make a responsive website in Figma Adapt from phone to desktop with auto layout, a frame per breakpoint, and variable modes that switch with the screen width.
- How to show different content per device A different component variant on touch or mouse, portrait or landscape, screen or print, from one variant property.
- How to make a Figma website accessible Headings, lists and image alt text, read from your layer names, text styles and lists.
- How to control the HTML of a Figma website Name a layer or text style with an HTML tag and it’s published as that tag, with its attributes.
- How to embed HTML in a Figma website Add widgets, maps, booking tools or third-party forms with the plugin’s Embed component and your own HTML.
- How to add videos to a Figma website YouTube and Vimeo players, MP4 video fills, GIFs, or an HTML video tag.
- How to add animations to a Figma website: GIF, Lottie, SVG GIFs, Lottie animations from the LottieFiles plugin, dotLottie and animated SVG.
- How to add 3D graphics to a Figma website Add interactive 3D to a website made in Figma: name a layer with a Spline viewer tag.
- How to animate elements on scroll in a Figma website Elements that smart-animate as they scroll into view, from one @appear variant property.
- How to build a working form in Figma Name layers form, input, label and button for a working form; submissions land in your dashboard.
- How to use Notion as a CMS for a Figma website Generate a page per Notion item, repeat layers per item, and fill text and images from its properties.
- How to add dark mode to a Figma website Light and dark variable modes that follow the visitor’s system setting, with an optional toggle.
- How to translate a Figma website into several languages One variable mode per language: visitors get theirs, and each language gets its own URL with hreflang.
- How to customize the 404 page of a Figma website Replace the default 404 page with your own /404 page, and redirect renamed or deleted pages.
How it works
A page is a section
Each page of the site is a top-level Section on the canvas.
The section name is the page path: the first page you add is the home page
/, the next ones /about,
/pricing, and so on. Adding a top-level frame as a page wraps
it in a section for you.
- Paths start with
/, up to 250 characters. -
Characters other than letters, digits and
- _ . ~become dashes. - A section holds 1 to 4 frames of different widths — one per breakpoint (see Responsive design).
-
A
/404page is your custom not-found page; without one, a default is published.
Preview and publish
Preview renders the page as the browser will, at phone (390), tablet (800), laptop (1440) and desktop (1920) widths, or any width you drag to. Publish builds the whole site and puts it live; plan limits (pages, images, videos) are checked at that moment.
The site is static: design edits, CMS content and settings such as redirects go live the next time you publish.
Responsive design
Start in Figma: give the page’s top frame auto layout that hugs its content vertically. A max width on it (auto layout required) is respected, and the page centers on wider screens.
Breakpoints with frames
When auto layout isn’t enough, put up to four frames of different widths in a page section — for example a 390 px phone frame and a 1440 px desktop frame. The frames are sorted by width and each one is used from its width up to the next one, so a visitor always gets the closest design. Between those widths, auto layout, constraints and min/max widths keep the layout fluid. With a single frame, that frame is used at every width. The narrowest frame ignores its min width, so phones never scroll sideways.
Keep the content in one place: make the page content a component and use an instance in each frame, overriding only what changes per breakpoint.
Website breakpoints
Settings → Breakpoints defines the site’s breakpoints: Phone 0–400, Tablet 401–768, Laptop 769–1024 and Desktop 1025+ by default. Phone and Desktop are always on; drag the separators to change the ranges, or reset them.
Variables by breakpoint
A variable collection whose modes are all named after breakpoints (phone or mobile, tablet,
laptop, desktop) switches mode with the viewport
width — handy for font sizes, spacing and visibility. Add number variables
named min-width / max-width
in the collection to override the ranges. You don’t need all four modes, and
you can combine variables with several frames.
Modes switch with the width in the preview and on the published site, not on the canvas. To see every size while designing, turn the page into a component and place one instance per mode outside the page section.
More than one variable mode needs a Figma Professional plan or above; this applies to languages and dark mode too.
Device-specific content
Add a variant property named @media to a component, with a CSS
media query as each variant’s value — pointer:fine (mouse), pointer:coarse (touch), hover:none, orientation:portrait, print… The matching variant shows. Combine queries with and, or a
comma for “or”. Figma doesn’t allow = in values; for width, use
the breakpoints above.
Layer names & HTML
Figma has no place for accessibility information, so figma.to.website
reads it from layer names: they decide the HTML tag, and the site gets a
real document outline for screen readers and search engines. Write the tag
itself, like <h1> or <nav>, or one
of these names:
| Layer name | HTML |
|---|---|
heading 1 … heading 6 | <h1> … <h6> |
paragraph | <p> |
link | <a> |
list, item | <ul>, <li> |
quote, abbreviation | <q>, <abbr> |
button, blockquote, menu…
| The tag of the same name |
hero#top | Sets id="top", an anchor you can link to |
-
A text style named
<h1>(orh1…h6,paragraph,quote) tags every text that uses it — one change for the whole site. -
A layer named with an HTML element, such as
<input name="email" type="email" required>, becomes that element, attributes included. -
Bulleted and numbered text lists become
<ul>and<ol>. -
A component with an on-click link action becomes a link (
<a>); with any other click action, a<button>. -
An image layer’s name is its
alttext — name images for what they show.
Interactions & animation
Prototype interactions are converted, so the published site behaves like your prototype.
| Triggers | On click, on press, on drag, while hovering, mouse enter/leave/down/up, key down, after delay |
|---|---|
| Actions | Navigate to (a page of the site becomes a link), change to (variants), open/swap/close overlay, scroll to, back, open link, set variable, set variable mode, conditional, video controls |
| Transitions | Instant and smart animate, with your easing and duration |
Links
-
Select some text, add a link and enter a page path such as
/pricing— the section name of that page — or an external URL. Figma shows the path ashttps:///pricing; that’s expected, and it links to your page. - A Navigate to interaction on a frame becomes a link to that page. Page-to-page transitions are instant.
- Open link interactions become links too. Figma’s API doesn’t expose its “open in new tab” option, so it has no effect.
Animate on scroll
Give a component a variant property named @appear, with
true and false variants, and use the @appear=true variant in your design. On the web, it starts as @appear=false and smart-animates to @appear=true when it scrolls into view
(300 ms by default) — a fade or slide-in without code. To change the transition,
add a Mouse enter or While hovering interaction to the
@appear=false variant: it fires on scroll, no mouse needed.
Motion graphics & 3D
- GIF: drop it in Figma; it publishes as is.
- Lottie: insert it with the LottieFiles Figma plugin and
it publishes as a live Lottie animation — or name a layer
<dotlottie-wc src="…" autoplay loop>. - Animated SVG: name a layer
<img src="https://…/animation.svg">; the file is hosted elsewhere. - Spline 3D: name a layer
<spline-viewer url="…/scene.splinecode">, with the URL from Spline’s Export → Viewer.
For Lottie and Spline, the script that runs them is added for you.
Images & video
- Use full-resolution images: they are resized for each screen and served as WebP/AVIF, lazy loaded below the fold. Use PNG for lossless images like screenshots, JPEG for photos.
-
Add
!zoomableto an image layer name to open it full screen on click, or!fullsizeto skip resizing. -
Figma video fills become
<video>, muted, autoplaying and looping like in Figma; add!autoplayor!loopto the layer name to turn either off. -
MP4 video fills (a Figma Professional feature) only publish from public
Figma files, for now. In a private file, name a layer
<video controls src="https://…/video.mp4">, with the file hosted elsewhere. - YouTube and Vimeo players are ready-made components in the plugin’s Components tab: drop one in and fill in its properties.
The number of images and videos per site depends on the plan (see Plans & limits).
Full guide
Notion CMS
Use a Notion database as your site’s content: a blog, a portfolio, a job
board. Pages are templated with Twig: generate a page per item, or repeat
layers per item. In the plugin’s CMS tab, click Connect to Notion, pick a
database and name the collection (for example posts). If a
database is missing from the list, share it with the figma.to.website
integration in Notion.
| To | Do this |
|---|---|
| Repeat a layer per item |
Name the parent frame {% for item in posts %}; its first child is repeated. Sort with {% for item in posts|sort_by('date') %} (descending; add , 'asc' for ascending).
|
| Show a property |
Write {{ item.title }} in a text,
or in a layer name
|
| Show an image |
Name a rectangle or frame with one image fill {{ item.cover }} |
| Link to an item | Use the property in an Open link interaction or a text link |
| Format a date | {{ item.date | date("F j, Y") }} |
| One page per item |
Name the page section /blog/[posts]; each item’s
slug property is its URL, or its title without one ([posts:url_path] to use another property). Add a slug so renaming a post doesn’t change
its URL.
|
The CMS tab shows your collections and their first 10 items, to check property names; Preview shows the result with real content. Content is fetched when you publish: republish after editing Notion.
RSS
Set a page’s Open Graph type to article (page settings → Social) and
it is added to the site’s RSS feed, at /feed/en.xml
— one feed per language.
Forms
Design the form as you like; layer names make it work.
-
Group the fields, labels and button in a frame named
<form id="contact">. -
Name each field
<input id="email" name="email" type="email" required>or<textarea name="message">— every field needs aname, the key it is sent under. Any HTML inputtypeworks: text, email, tel, number, date, checkbox, radio, file… A text layer’s content becomes the placeholder. -
Name each field’s text label
<label for="email">, with the field’sid. Optional, but screen readers and visitors benefit. -
Name the button
<button type="submit">: it validates the form and sends it.
Submissions land in the Forms tab of the plugin and in the web dashboard, where you filter them by form and download them as CSV. Spam protection is built in. Only the fields declared in the form are stored.
Each plan includes a number of submissions a month. Past it, submissions are still collected, and they show once the site is upgraded.
Prefer a ready-made form? Typeform, Tally, Mailchimp, Brevo and other form builders drop in with an Embed.
Full guide
Localization & dark mode
Languages
Put your copy in variables (text, or any type: images, sizes…) in a
collection whose modes are all language codes (BCP 47: en, fr, pt-BR…). The mode selected on the canvas is the default
language; change it in Settings → Localisation.
Visitors get their browser’s language. Each language is also published at
its own URL — the default at the root, the others under their mode name (/fr/, /fr/contact-us/) — with lang, canonical and hreflang set so search engines index every language.
For a language switcher, give its options a Set variable mode interaction; the visitor’s choice is remembered.
Dark mode
A color collection with modes named light and dark follows the visitor’s system setting. For a toggle, add a text variable (say
theme, valued light / dark per mode),
build a switch component with light and dark variants whose On click action
is Set variable mode, and bind the instance’s variant to theme.
SEO
| Site-wide | Default title and description, Open Graph title, description and image (any layer, rendered at 1200×630), language, favicon (light and dark), canonical domain |
|---|---|
| Per page | Title, description, Open Graph, no index / no follow, sitemap priority and change frequency |
| Automatic |
Canonical URLs, sitemap.xml and robots.txt, IndexNow ping on publish, hreflang, RSS
|
CMS properties work in titles and descriptions too, e.g. {{ item.title }} on a /blog/[posts] page. Name your headings (see Layer names & HTML) — the page outline matters to search and answer engines.
Domains
Free address
Every site gets <name>.figweb.site. Rename it in
Settings (5–32 letters, digits or dashes); the old address stops working.
Custom domain
From Level 1, in Settings → Domains:
-
Enter your domain. A bare domain becomes
www.example.com. -
At your registrar, add a
CNAMErecord pointing tocname.figweb.xyz, and theTXTrecord shown while SSL is pending. - Refresh the status until domain and SSL are both active.
The first custom domain is the primary one; the others redirect to it. Redirects from old URLs are set in Settings → Redirects.
Fonts
Google Fonts and web-safe fonts are included automatically. For a font installed on your computer, download and run the figma.to.website agent (Windows, macOS, Linux) from Settings → Fonts, keep it running while you publish, and it uploads the font. You must own a license that allows web use.
Custom code & analytics
- Analytics: Google Analytics / Tag Manager, Fathom or Plausible, with just your ID, in Settings → Analytics.
- Code in
<head>and<body>: site-wide in Settings → Custom code, or per page in page settings (10 KB each). - Embeds: for larger blocks of HTML, drop the Embed component
(Components tab → Advanced components) and edit its HTML in the Embeds tab
— maps, widgets, booking tools, third-party forms. Component properties are
available as
{{ prop }}.
Full guide
Password protection
From Level 2, protect the whole site or single pages, and give a page its own password or none. Pages are encrypted with the password and decrypted in the visitor’s browser; the password itself is never stored.
Hosting & code export
Sites are served from Cloudflare’s global network (300+ locations) over HTTP/3, with compressed and minified HTML, CSS and JS, responsive images and unlimited visitors and bandwidth on every plan.
From Level 1, Settings → Hosting → Download website code gives you a ZIP of the published static files, to host anywhere.
Plans & limits
Plans are per site, billed monthly or yearly. Every level includes unlimited visitors and bandwidth, the global CDN, SEO settings and a custom 404 page. figma.to.website is not part of ‹div›RIOTS ONE.
| Level | Price per month | Pages | Images | Videos | Custom domains | Redirects | Form submissions / month | Publishers |
|---|---|---|---|---|---|---|---|---|
| Level 0 | Free | 10 | 50 | 0 | 0 | 1 | 15 | 1 |
| Level 1 | $10, or $5 billed yearly | 10 | 100 | 1 | 2 | 10 | 30 | 1 |
| Level 2 | $15, or $10 billed yearly | 100 | 1,000 | 3 | 2 | 10 | 500 | 2 |
| Level 3 | $30, or $20 billed yearly | 1,000 | 10,000 | 10 | 5 | 100 | 2,000 | 5 |
| Level 4 | $60, or $40 billed yearly | 10,000 | 100,000 | 20 | 10 | 1,000 | 10,000 | 10 |
- Level 1 adds custom domains, removes the “Made with figma.to.website” badge and unlocks code download.
- Level 2 adds password protection.
- Levels 3 and 4 are for large sites, up to 10,000 pages.
Upgrade a site from the plugin or the dashboard. Compare levels on the pricing section.
How to use
- Install figma.to.website from Figma Community and run it in a Figma Design file.
- Start from a blank site, a template, or select your own frame and click Start with selected frame.
- Add a page per top-level section, named with its path, and a frame per breakpoint inside each.
- Name headings, links and form fields; add your interactions, CMS bindings and settings.
- Preview at each width.
-
Log in and click Publish — your site is live at
<name>.figweb.site.
FAQ
Is figma.to.website free?
Yes — the free level publishes a site on a *.figweb.site address with up to 10 pages, 50 images and 15 form submissions a month, unlimited visitors and bandwidth. Paid levels, billed per site, add custom domains, more pages and media, password protection and code download. See Plans & limits.
How is it different from Figma Sites?
figma.to.website publishes from any Figma Design file through a plugin, and adds what a real site needs: Notion as a CMS with dynamic pages and RSS, built-in forms, localization from variable modes, dark mode, custom code, analytics, redirects, password protection and a code download.
What makes a page?
A top-level Section on the canvas. Its name is the page path (/, /about, /blog/[posts]), and it holds up to 4 frames of different widths, one per breakpoint.
Is the site responsive?
Yes. Give a page a frame per breakpoint — phone, tablet, laptop, desktop — and each frame is used from its width up to the next one. Auto layout and constraints stay fluid in between, and variable modes named after the breakpoints switch automatically.
Do prototype interactions work on the published site?
Yes. On-click, hover, press, drag, key and after-delay triggers convert, with navigate, overlay, scroll-to, open-link, change-to (variants, smart animate), set-variable and conditional actions.
Which CMS does it support?
Notion. Connect a Notion database, then bind its properties to layers with {{ item.property }} and repeat a layer with {% for item in collection %}. A section named /blog/[posts] generates one page per item.
Where do form submissions go?
To your figma.to.website dashboard (the Forms tab in the plugin, or the web dashboard), where you can filter them by form and download them as CSV.
Can I use my own domain?
Yes, from Level 1: add a CNAME to cname.figweb.xyz at your registrar. SSL is issued automatically.
Can I use custom fonts?
Yes. Google Fonts are included automatically; for fonts installed on your machine, run the figma.to.website agent while you publish and it uploads them. You must own the license for web use.
Can I download the code and host it myself?
Yes, from Level 1: Settings → Hosting → Download website code gives you a ZIP of the published static files.
Do I need to republish after editing the design or the Notion content?
Yes. Publishing builds a static site from the current design and fetches the CMS content at that moment, so republish to push changes live.
Do I need a paid Figma plan?
No for most of it. Responsive variables, languages and dark mode use several variable modes in one collection, which Figma reserves for its Professional plan and above.
Is it part of ‹div›RIOTS ONE?
No. figma.to.website is billed per site, monthly or yearly — see Plans & limits.
Support
Stuck, or a design that doesn’t publish the way you expect? Email us at [email protected], or ask the community on Discord. A link to the site, or the Figma file, helps us help you faster.