← Widgets

A roadmap embedded on your own domain, on any plan

A public roadmap on somebody else's domain is a roadmap your customers have to be sent to. This widget lets you embed it inside a page you already own, at an address you already have, styled the way your site is styled.

There is a distinction here that trips people up, so it goes first.

Do I need the PRO plan to put the roadmap on my own site?

No. The embed works on the nine dollar plan.

The thing that needs PRO is a custom domain for the hosted board, which is a different feature. That points your own domain name at a board we serve. The widget does not do that, it draws the roadmap inside a page your own server is already serving, which is why it needs nothing extra.

For a lot of people the widget is what they actually wanted when they went looking for a custom domain. It is worth knowing before you buy the more expensive plan for the wrong reason.

If you want to try the embed on a real page, start a 14 day trial with a card at signup and copy the key from the board.

The same public board rendered under a customer's own accent colour
The same public board in a customer's own accent colour.

What is the line you paste?

Two tags that load the widget and one call that mounts it.

<link rel="stylesheet" href="https://app.votefirst.app/embed/votefirst.css">
<script src="https://app.votefirst.app/embed/votefirst.js"></script>
<script>
  VoteFirst.init({ project: 'your-project-slug', key: 'your-embed-key' });
  VoteFirst.roadmap('#votefirst-roadmap');
</script>

<div id="votefirst-roadmap"></div>

The stylesheet line is optional. Leave it out and the widget arrives with no styling at all, which is what you want if you would rather write every rule yourself.

The project slug and the embed key both come from your own board's settings, and the key is public by design, because it only ever reads what the board already publishes.

What does it draw?

Your columns as a grid of feature cards.

By default that is Suggested, Denied, In Review, In Progress and Completed, exactly as on the hosted roadmap. Denied is on by default rather than hidden, so your declined work is visible unless you decide otherwise. An archived column is the opposite and stays hidden until you turn it on.

Each column header carries its own total, which is the total on the board rather than the number currently drawn. Twenty cards load per column and a control at the foot of each one fetches the next twenty, so a column holding four hundred requests does not arrive as four hundred cards.

The order inside a column is the order you arranged on your own board. That is the default rather than most voted, because the board a visitor sees on the hosted page is the board you built, and an embed that quietly reordered it would be showing them something else.

Can I draw only some of the columns?

Yes, and this is the option most people want and do not know exists.

You can name the columns you want and the widget draws those. A marketing page that should show In Progress and Completed and nothing else is two words of configuration rather than a second board.

If you name a column this board does not have, you get a message saying the board is empty rather than a blank box. That reads as the widget failing, so it was fixed once and is worth knowing about.

You can also bake a tag filter or a search term into the embed, which is how one page shows the mobile requests and another shows the billing ones off the same board.

What happens if one column fails to load?

That column says so and the rest of the board still draws.

Each column is fetched on its own and each one handles its own failure, so a request that times out becomes an error message inside that column while the other four render normally. A roadmap that vanishes entirely because one query was slow is a worse page than a roadmap with one column apologising.

The private board, with Pending approval holding four suggestions nobody has let through yet, Suggested beside it and Denied with the reason written on each card
The private board, where every new suggestion waits for approval.

Can visitors vote on it without an account?

Yes, and they can comment and suggest too, subject to the switches you set.

The first write mints an anonymous identity in their own browser. No cookies, no credentials, and a token bound to your project so it cannot be replayed elsewhere.

Voting is set per column rather than once for the whole board. You choose which columns accept a vote, so a board that takes votes on Suggested and In Review while Completed is read only is an ordinary setup rather than a workaround.

The widget is told which columns those are, and draws the vote control from that answer. It does not offer a vote and then discover it was refused, which is the behaviour that makes an embedded board feel broken.

Revenue figures never appear. No multiplier, no tier name and no MRR value is in the payload the widget reads, and the one route that reads money refuses an embed key, so a published key cannot reach it.

Cards carry the plain vote count until you switch on weighted voting, and then they carry the weighted total instead. That is worth knowing before you embed it, because it differs from the hosted page, which keeps showing the headcount, and no option changes it either way.

The voter list, one row per person, showing where each arrived from and how many requests and comments they have left
Everyone who voted, one row each, no account required.

Can I make it match my site?

Yes. You set the background, the main and secondary text colours, the accent, the card background, the border, the font and the corner radius, separately for dark and light.

Dark is the default. Six fonts are available. Everything you configure for the hosted board carries into the widget, so you set it once.

If that is not enough, every column is drawn as a section carrying its own data-column-id and, where it has one, its data-status. Your own stylesheet can reach a single column through those without us needing a setting for it.

There is no badge on a paying account. The Powered by mark is drawn only when the owner has no live plan, so paying for the smaller plan is what removes it, and nothing is charged separately to take it off.

14 days, a card at signup, then $9 or $39 a month.

Should I use the widget or the hosted board?

Use the widget when the roadmap belongs inside your product or your marketing site, and when you want the surrounding page to be yours.

Use the hosted board when you want an address you can send people to from an email or a support reply, and when you would rather not touch your own site to change how the roadmap looks.

Most people who use both put the widget in the product and link the hosted board from support conversations, and the other widgets work the same way. There is no extra charge for running both, because it is one board rendered twice.

What it cannot do

It cannot draw a board that is not public. There is no private board at any price, so an embed on a page behind your own login still draws a roadmap anybody holding the public key can read.

How do I install it?

One script tag with your project and your public key, and a container where the grid should go. It finds the container and starts itself. The three step version of that is the embed quickstart.

If you want to decide when it appears, load the stylesheet and script and call the setup yourself. Early calls queue rather than fail. A pinned version address is available if you want one exact build, cached for a year.

One thing worth knowing if you run more than one board. The roadmap widget and the board widget are the same renderer, and the roadmap one is simply pointed at your main board by default.

If your account has several public boards, you name the one you want and the same widget draws it, which means anything on this page about columns, paging, filters and per column voting is true of all of them.

The roadmap widget embedded in an ordinary web page, drawing the board's columns as a grid of cards
The roadmap widget running inside an ordinary web page.

Related reading

A changelog widget that builds itself from the board A feedback widget that shows the board, not just a form