figma.to.website Docs

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.

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 /404 page 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> (or h1…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 alt text — 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 as https:///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 !zoomable to an image layer name to open it full screen on click, or !fullsize to skip resizing.
  • Figma video fills become <video>, muted, autoplaying and looping like in Figma; add !autoplay or !loop to 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).

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.

  1. Group the fields, labels and button in a frame named <form id="contact">.
  2. Name each field <input id="email" name="email" type="email" required> or <textarea name="message"> — every field needs a name, the key it is sent under. Any HTML input type works: text, email, tel, number, date, checkbox, radio, file… A text layer’s content becomes the placeholder.
  3. Name each field’s text label <label for="email">, with the field’s id. Optional, but screen readers and visitors benefit.
  4. 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.

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:

  1. Enter your domain. A bare domain becomes www.example.com.
  2. At your registrar, add a CNAME record pointing to cname.figweb.xyz, and the TXT record shown while SSL is pending.
  3. 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 }}.

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

  1. Install figma.to.website from Figma Community and run it in a Figma Design file.
  2. Start from a blank site, a template, or select your own frame and click Start with selected frame.
  3. Add a page per top-level section, named with its path, and a frame per breakpoint inside each.
  4. Name headings, links and form fields; add your interactions, CMS bindings and settings.
  5. Preview at each width.
  6. 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.

See also