Skip to content
MintGuides

Go live

Site widgets

Ready-made pieces for your own site — sign-in, a cart, checkout and order history — added with one script and styled to match.

Open Widgets
On this page

Add a widget

The Widgets page starts empty. Add the widgets you want one at a time; a short setup walks you through each.

Open Widgets and press Add a widget. The setup takes a few steps:

StepWhat you do
WidgetPick one: Login & account, Cart, Checkout, Thank-you page or My orders. Widgets that are coming soon show greyed out.
CustomersLogin & account only: MINT’s Customers (the default) or a model of your own. See Your customer model.
ShopCart, Checkout, Thank-you page and My orders: which model holds your products (and, for all but the cart, where orders go). The Shop settings are right there to fill in and save.
Set upThe widget’s options, such as a card or a button, and what it asks for.
TextsEvery word it shows, in your words or your visitors’ language. Leave one as it is to keep the default.
ReviewA preview, the code to put on your page, and Switch it on now. Press Add widget.

Added widgets are listed on the Widgets page. Each one has a switch to turn it on or off straight away, Edit (the same steps again, without picking the widget) and Remove. Removing takes it off your site at once and puts its settings back to the defaults; you can add it again any time.

A selling widget can be added before the Shop is set up. It’s added switched off, with a note saying what’s missing; switch it on once the Shop is saved.

Add MINT to your site

One script tag per page, then put each widget where it should appear.

Widgets are ready-made pieces for a website or app you host yourself: sign-in, a cart, checkout and order history today, with forms and more on the way. They talk to your project’s public API, so any project with one can use them, websites and APIs alike. Find them in the panel under Site → Widgets (websites) or next to the Public API (other projects).

<script src="https://mint-c5e1255519fc.herokuapp.com/public/mint.js" data-key="<project key>" async></script>

The Widgets page has this tag ready with your project filled in. Put it in <head> or just before </body>. Then place a widget with its snippet, such as <div data-mint="login"></div>, or as a tag: <mint-login></mint-login>.

  • A widget shows only once it’s added and switched on. Switch it off (or remove it) and it disappears from your site within a minute.
  • Each widget’s code loads only on pages that use it.
  • Widgets draw in their own sealed area: your CSS can’t break them and theirs can’t touch your page.
  • Widgets added to the page later (single-page apps, pop-ups) are picked up too.

The look

Colour, font, corners and light or dark, shared by every widget.

SettingWhat it does
ColourButtons and links. Leave it empty on a website to use the colour from Site setup.
FontA font your site already loads, e.g. Inter. Empty: whatever the page around the widget uses.
CornersHow round cards, buttons and fields are, 0–24 pixels.
Light or darkMatch the page looks at the background behind each widget: light on light pages, dark on dark ones. Or pick Always light / Always dark.

The Look panel appears once you’ve added a widget, and has its own Save. Each widget’s setup ends with a live preview on a light or dark page, showing your settings before anything goes live.

Login & account

Sign in and sign up for your project’s customers; once signed in, their name and a sign-out link.

It uses the same customer accounts as the public API’s signed-in endpoints. See Customers for how those accounts work.

OptionChoices
LayoutA card on the page (suits an account page), or a button that opens the card (suits a header).
Opens onSign in or Create an account: which form shows first.
Let visitors create accountsOff: only people who already have an account can sign in.
Ask for a phone number on sign-upAdds an optional phone field. It’s kept with the account and copied to your customer model’s phone field.
Customer role (this login)Everyone (one login for all), or one customer role — a seller login, say. See A login per customer role.
Show “Forgot your password?”On by default. Emails a link to choose a new password — see Forgot password.

Under Texts you can reword every title, button and link, for example into your own language. In the signed-in text, {name} becomes the customer’s name.

To change an option on one page only, add it to the element as a data- attribute:

<div data-mint="login" data-layout="button"></div>
<mint-login data-start-with="signup"></mint-login>
Pages written for the older widget (widget.js with data-mint-login) keep working. Switching to mint.js gets you the panel’s options, texts and look.

Your customer model

Accounts are kept in MINT’s Customers by default. You can keep them with a model of your own instead.

Out of the box, everyone who signs up is on your Customers page. If you have a model of your own for customers, for example Members or Customers, first open it to sign-in: switch on People can sign up and sign in on the model’s Advanced tab. Only models switched on there are offered. Then pick it in the widget setup’s Customers step, choose which fields hold the email, name and phone, then choose how:

HowWhat happens
Keep accounts in MINT’s Customers, with a copy hereAccounts stay on your Customers page, and each one also gets a record in your model (or is linked to the record with the same email, in any capitals). Accounts made earlier get their record the next time they sign in. Your team can edit or remove those records; the accounts carry on.
This model holds the accountsEvery sign-up is a record in your model and isn’t on the Customers page. The record’s email is what signs in, so if your team changes it, the customer signs in with the new one. Removing (or archiving) the record ends that account and signs it out. Records your team adds have no password, so they can’t sign in, and nobody can take one over by signing up with its email. Accounts made before you switched keep signing in as MINT customers.

Either way, passwords never go into your model: MINT keeps them safely (scrambled, never shown to anyone), along with staying signed in and signing out everywhere. When a customer changes their name or phone on your site, their record changes too.

FieldNeeds
EmailRequired. An Email or Text field.
NameOptional. A Text field, filled from the sign-up form.
PhoneOptional. A Text field. Turn on Ask for a phone number on sign-up to collect one.
Customer roleOptional. An Options field, such as Customer role with Customer, Seller and Picker. See Customer roles.

The model must be a list (not a single record), and any other required field needs a default value, because the record is made from the sign-up form alone. The panel says so if it doesn’t fit. If you later remove a field you picked, sign-up keeps working; the setup then tells you to pick the fields again.

Your own code sees the record’s ID as Mint.auth.user.record. With your model’s public API on, signed-in and owner-only, a customer can read and update the record their sign-up made, and nobody else’s. A record your team made earlier is linked but not handed over, because an email address alone doesn’t prove who someone is.

Customer roles

One sign-in model for all your customers; a Customer role field tells kinds of customers apart.

A project has one sign-in model. Rather than a model each for customers, members and staff, give that model an Options field such as Customer role (Customer, Seller, Picker…) and choose it as the Customer role in the widget’s Customers step. Everyone signs in the same way, with one password, and an email belongs to one account.

  • New sign-ups get the field’s default. Give it one, such as Customer.
  • Only your team changes a customer role, on the record in the panel. Your site and the API can’t, so nobody can make themselves a seller.
  • These are your customers’ roles. Your team’s roles (Project → Members → Roles) are separate and don’t mix with them.
  • A change counts straight away. The customer doesn’t need to sign in again.
  • On an endpoint for signed-in customers, tick Which customer roles to let in only those (see Who can call it). A rule can also compare a field with their customer role.
  • Your own code sees it as Mint.auth.user.customerRole.
  • A record your team made before the person signed up (linked by email) gives them no customer role. An email address alone doesn’t prove who someone is. Set the customer role on their record once you know.

Details that only some customers have, such as a seller’s shop name, can live in a model of their own that links to the sign-in model.

A login per customer role

A sellers’ login, a pickers’ login: each lets in its own customer role.

Put a login on a page for one customer role with data-customer-role, or set the widget’s Customer role (this login) for every page:

<div data-mint="login" data-customer-role="seller"></div>
  • Only accounts with that customer role sign in there. Anyone else is told it’s for another kind of account, and gets no session.
  • Its Create an account makes that role, but only for roles you switch on under Who can sign up as each customer role in the widget’s Customers step. The default role is always on. For the others (pickers, staff), the link doesn’t show, and your team gives the role on the record.
  • Protect what each role uses with endpoints: give sellers their own paths (/seller/orders) and tick Which customer roles on them.
  • Your own form can do the same: Mint.auth.signIn(email, password, { customerRole: 'seller' }) and Mint.auth.signUp({ …, customerRole: 'seller' }).
  • Signing up with the email of a record your team already made links that record but gives no customer role. Set it on the record once you know who they are.

Forgot password

Customers who forget their password get an email with a link to choose a new one.

Under the sign-in form there’s a Forgot your password? link. The customer types their email and is told a link is on its way. They see the same message whether or not that email has an account, so nobody can use it to find out who your customers are. It works the same for accounts in MINT’s Customers and accounts your own model holds.

  • The email comes from your project’s own email account (Project → Email, or your organization’s). Until one is set up, visitors are told the email can’t be sent.
  • The link leads back to the page they asked from, as long as it’s on one of your project’s domains. Anywhere else, it opens a Choose a new password page hosted by MINT, so a link never goes to a site that isn’t yours.
  • The link works once, for an hour. Setting the new password signs them in there and signs them out on every other device.

The email shows in your email log as Password reset, using your email design. To hide the link, switch off Show “Forgot your password?” in the widget’s options. Building your own form? Use Mint.auth.forgotPassword and resetPassword.

Shop

Tell the widgets which model is your catalogue. The cart, and later checkout, read prices and stock from it.

Widgets don’t assume what your models are called. In a selling widget’s setup (its Shop step), or under Shop on the Widgets page once one is added, pick the model that holds your products and say what its fields mean. If your project came from the E-commerce or Products & orders template, this is filled in for you: check it and save.

PartWhat it is
Name, PriceRequired. A text field and a number (or formula) field.
Compare-at priceThe old price, shown crossed out when it’s higher than the price.
ImageAn image or images field; the first image shows in the cart.
StockA number field. Leave it as none if you never run out. A cart can’t hold more than is in stock.
StatusWhich values mean for sale, e.g. Active. Drafts and archived products can’t be added to a cart.
VariantsA list field (sizes, colours) with a name, then either the product’s price plus or minus, or a price of its own, and optionally its own stock.
Carts kept inMINT (nothing to set up), or a model of yours with a link to the products model and a quantity field. Your own model shows every cart line as a record your team sees; its public API must be on, owner-only.
CurrencyThe three-letter code your prices are in, e.g. BDT or USD.
Prices are always read from your catalogue on our server. A page can’t change what something costs, however its code is edited. Change a price in the panel and every cart shows the new one.

Cart

Add-to-cart buttons on any product, a cart button with a count, and a cart drawer.

Set up the Shop first, then switch the Cart on. Put the cart where it should show, and data-mint-add on any button with the product’s ID (the ID on its record page):

<div data-mint="cart"></div>

<button data-mint-add="PRODUCT_ID">Add to cart</button>
<button data-mint-add="PRODUCT_ID" data-mint-variant="Large" data-mint-quantity="2">Add two, large</button>

A product with variants opens a picker that shows each variant’s price and which ones are sold out. Name the variant with data-mint-variant to skip it.

OptionChoices
LayoutA cart button that opens a drawer (suits a header), or the cart itself on the page (suits a /cart page).
Checkout pageWhere the Checkout button goes, e.g. /checkout. Empty: no Checkout button. The checkout widget is coming next.
Open the cart when something’s addedOff: a short “Added to your cart” message instead.

Guests and accounts. A guest’s cart is kept in their browser. When they sign in or create an account, it joins their account’s cart, and from then on it follows them between phone and laptop. Signing out leaves an empty cart on that browser.

Stock and prices. If someone asks for more than you have, the quantity is cut to what’s in stock and the cart says so. Sold-out products stay in the cart, marked, and aren’t counted in the subtotal. Products you stop selling disappear from carts.

The Shop’s orders

For checkout: which model orders are written to, and what its fields mean.

PartWhat it is
Orders model, items listA model with a list of items (a repeating group) — each item a product name, quantity and unit price, and optionally variant, SKU and a link to the product.
StatusWhich value means waiting for payment (new orders), which means paid (set only when the provider confirms) and, optionally, cancelled.
The buyer and the moneyEmail, name, phone, delivery address (a group of fields or one text box), note, total, delivery cost, payment reference — whichever your model has.
Saving makes the order’s status and payment reference read-only on your public API, so a page can’t mark an order paid. The E-commerce and Products & orders templates are filled in for you.

Checkout

The buyer’s details, the order summary at your prices, and Pay.

Put it on your checkout page and set the Cart’s Checkout page to that address. It needs the Shop’s orders and a way to pay switched on in Payments.

<div data-mint="checkout"></div>
OptionChoices
Ask for a phone numberOn by default — couriers often need one.
Ask for a delivery addressOff for things that aren’t delivered.
Let buyers add a noteDelivery instructions, a gift message.
Buyers must have an accountOff: guests pay with just an email.

With more than one provider switched on, the buyer picks how to pay (card through Stripe, SSLCommerz, bKash). Pay writes the order as waiting for payment and sends the buyer to that provider’s page. If something in the cart changed meanwhile (a price, sold out), the widget says so and shows the cart as it is now.

Thank-you page

Where buyers come back to after paying.

<div data-mint="thanks"></div>

It reads the payment’s reference from the page’s address (?ref=…), waits for the provider’s confirmation — usually a second or two — and shows the order number and what was bought. A guest’s cart is emptied then.

My orders

A signed-in customer’s own orders, for an account page.

<div data-mint="login"></div>
<div data-mint="orders"></div>

Each order shows its number, date, status (as your team sets it — Paid, Packed, Shipped…), total and items.

Mint in your own code

mint.js gives your page’s scripts window.Mint.

UseDoes
await Mint.auth.readyWaits until the stored sign-in has been checked; gives the customer or null.
Mint.auth.userThe signed-in customer, or null. .record is their record in your customer model, when you picked one; .customerRole their customer role, or null.
Mint.auth.signIn(email, password)Signs in from your own form.
Mint.auth.signUp({ name, email, password, phone })Creates the account and signs in. The phone is optional.
Mint.auth.signOut()Signs out on this browser.
Mint.auth.forgotPassword(email)Emails a link back to this page to choose a new password.
Mint.auth.resetPassword(token, password)Sets the new password and signs in. When the page is opened from the link, the token is Mint.auth.resetToken (taken out of the address bar).
Mint.auth.onChange(cb)Calls cb with the customer (or null) on every sign-in and sign-out.
Mint.api(path, init)Calls your public API, as the customer when one is signed in. Gives a fetch Response.
Mint.on(event, cb)Listens for widget events, e.g. auth or cart. They also fire on document as mint:auth, mint:cart.
await Mint.cart.readyWaits until the cart is loaded. Then Mint.cart.lines, .count, .subtotal and .currency are set.
Mint.cart.add(id, { variant, quantity })Adds a product. Gives the updated cart.
Mint.cart.set(id, quantity, variant)Sets a line’s quantity; 0 removes it. Also remove(id, variant) and clear().
Mint.cart.product(id)A product as the cart sees it: name, price, variants with their price and stock.
Mint.cart.format(amount)An amount in your currency, written the visitor’s way.
<script>
  document.addEventListener('mint:auth', e => {
    document.body.classList.toggle('signed-in', !!e.detail);
  });
  async function myOrders() {
    await Mint.auth.ready;
    if (!Mint.auth.user) return [];
    const res = await Mint.api('orders?sort=-createdAt');
    return (await res.json()).doc;
  }
</script>

window.MintAuth still works and is the same object as Mint.auth.

Coming next

Being built now, roughly in this order.

  • More ways to pay: cash on delivery and bank transfer everywhere, and refunds. Stripe works now, and in Bangladesh SSLCommerz and bKash too — which ones you can use depends on your organization’s country, set in organization settings; see Payments.
  • Forms: contact and newsletter forms built from your models, with spam protection.
  • Booking: free slots worked out on the server, so there are no double bookings.
  • WhatsApp button, cookie consent and search.

Troubleshooting

SymptomWhy, and what to do
Nothing showsIs the widget added and switched on? Is the script’s data-key the project key from API → Keys? The browser console says which.
A change doesn’t showSites pick up saved changes within a minute. Reload the page.
The colours clash with my pageSet Light or dark to Always light or Always dark, or pick a colour under Look.
Signed in, but my API calls get 401Use Mint.api: plain fetch doesn’t send the customer’s token.
The cart won’t switch onSet up the Shop first and save it.
Sign-ups don’t show in my modelCheck the customer model in the widget’s setup (Edit → Customers). If a field you picked was removed or renamed, pick it again.
An add-to-cart button does nothingCheck the product ID (a wrong one, or a product that isn’t for sale, shows “Not found”) and that it isn’t sold out.