A barber price list on a page, behind a QR code at the chair

Services, minutes and prices on one phone-sized page, opened by pointing a camera at a sign. When a price changes you edit the page, and the sign on the wall stays as it is.

A barber price list works well as one web page that opens from a QR code at the chair. The client points the phone camera at the sign, the services and prices appear, and nobody downloads a file or an app.

People ask how to create a brochure online for this kind of job. For a price list you do not need design software: one page with a short list is enough, and an AI chat can write it in a minute.

Here is a page you can copy. The shop is made up and the prices are examples. Scroll inside the frame, then replace the names and numbers with yours.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Corner Cut Barbers - Prices</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui, sans-serif; background: #f3f1ed; color: #1f2430; }
  header { background: #1f2430; color: #fff; padding: 22px 20px 18px; text-align: center; }
  header svg { width: 34px; height: 34px; }
  header h1 { margin: 6px 0 2px; font-size: 24px; letter-spacing: .5px; }
  header p { margin: 0; font-size: 13px; color: #c9ced9; }
  main { max-width: 560px; margin: 0 auto; padding: 16px 16px 28px; }
  .updated { text-align: center; font-size: 13px; color: #5b6272; margin: 4px 0 14px; }
  section { background: #fff; border-radius: 12px; padding: 14px 16px 8px; margin-bottom: 14px; box-shadow: 0 1px 4px rgba(0,0,0,.08); }
  h2 { margin: 0 0 6px; font-size: 13px; letter-spacing: 1.2px; text-transform: uppercase; color: #9a3412; }
  .row { display: flex; align-items: baseline; gap: 8px; padding: 9px 0; border-top: 1px solid #eceef2; }
  .row:first-of-type { border-top: 0; }
  .name { font-weight: 600; }
  .note { display: block; font-weight: 400; font-size: 13px; color: #5b6272; }
  .dots { flex: 1; border-bottom: 1px dotted #b8bdc9; transform: translateY(-4px); min-width: 12px; }
  .price { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .info { font-size: 14px; line-height: 1.55; text-align: center; color: #3a4150; }
  .info b { color: #1f2430; }
</style>
</head>
<body>
<header>
  <svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.8" stroke-linecap="round" aria-hidden="true">
    <circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M8.5 7.5L20 18M8.5 16.5L20 6"/>
  </svg>
  <h1>Corner Cut Barbers</h1>
  <p>Tue to Sat, 9:00 to 18:00 &middot; Walk-ins welcome</p>
</header>
<main>
  <p class="updated">Prices updated 1 October 2026 (example prices)</p>

  <section>
    <h2>Haircuts</h2>
    <div class="row"><span class="name">Classic cut<span class="note">Scissors and clipper, 30 min</span></span><span class="dots"></span><span class="price">$25</span></div>
    <div class="row"><span class="name">Skin fade<span class="note">40 min</span></span><span class="dots"></span><span class="price">$30</span></div>
    <div class="row"><span class="name">Kids cut<span class="note">Under 12, 25 min</span></span><span class="dots"></span><span class="price">$18</span></div>
    <div class="row"><span class="name">Senior cut<span class="note">Age 65 and over, 30 min</span></span><span class="dots"></span><span class="price">$20</span></div>
  </section>

  <section>
    <h2>Beard and shave</h2>
    <div class="row"><span class="name">Beard trim<span class="note">15 min</span></span><span class="dots"></span><span class="price">$12</span></div>
    <div class="row"><span class="name">Hot towel shave<span class="note">30 min</span></span><span class="dots"></span><span class="price">$28</span></div>
    <div class="row"><span class="name">Neck and line-up<span class="note">10 min</span></span><span class="dots"></span><span class="price">$8</span></div>
  </section>

  <section>
    <h2>Combos</h2>
    <div class="row"><span class="name">Cut + beard trim<span class="note">45 min</span></span><span class="dots"></span><span class="price">$34</span></div>
    <div class="row"><span class="name">Skin fade + hot towel shave<span class="note">65 min</span></span><span class="dots"></span><span class="price">$52</span></div>
  </section>

  <section class="info">
    <p><b>Cash and card.</b> Tips welcome.<br>Running late? Call 555-0142.</p>
  </section>
</main>
</body>
</html>
A barber price list as a phone-sized page: updated date, three groups, prices in a column. Example shop and example prices.

What goes on the page

A price list is read standing up or sitting in the chair, usually for a few seconds. So the page should answer three questions at once: what do you do, how long does it take, and what does it cost.

  • Updated date at the top. It tells the reader the prices are current. Price list link explains why this one line matters.
  • Name, minutes and price on one row. The price goes on the right, in a column, so the eye can run down it.
  • Groups with short headings. Haircuts, beard and shave, combos. Clients look for the thing they came for.
  • Payment and a phone number. One short line at the bottom.

Leave off anything you would not pin to the wall of the shop. Anyone who has the link can open the page.

Make it with AI

Paste the prompt below into ChatGPT, Claude or Gemini. Fill in the square brackets with your own shop and list.

Write one self-contained HTML page: a price list for a barber shop called [SHOP NAME].
Mobile first. It must be easy to read on a phone held at arm's length.
No external images, fonts or scripts.
Top: shop name, opening hours, and the line "Prices updated [DATE]".
Then groups with a heading each: Haircuts, Beard and shave, Combos.
Each service is one row: the name, the minutes in small grey text,
and the price on the right with a dotted line between.
Use exactly these services and prices. Do not add, remove or round anything:
[PASTE YOUR LIST: service, minutes, price]
Bottom: payment methods and a phone number for running late.
Return only the HTML.

Then check the result before it goes on a wall:

  • Every price. Compare the page with your own list, line by line. An AI can add a service you do not offer or change a number.
  • The date and the phone number. Both are easy to leave as a placeholder.
  • A narrow screen. Make your browser window narrow. If text is cramped, ask for a mobile-first layout. The viewport meta tag is usually the cause.
  • No pictures from other sites. Images loaded from other websites are blocked in NOS. Ask for an inline drawing or no picture.

Copy the HTML and paste it into a NOS document. Choose Create share link. HTML to link walks through it.

The client opens the link in a browser, on a phone too, with no account, and can read the page but not edit it. When you change a price, edit the code in your document. The link stays the same and shows the new version.

The QR code

A QR code encodes an address. Make one from your share link with any QR code generator you trust. QR code link covers size and contrast.

Scan it yourself before you print anything. Open the camera, point it at the code, and tap the link that appears.

Google's help for Pixel phones says you do not need to take a picture, and that Camera scan suggestions must be turned on in Camera settings.

Apple has a guide called "Scan a QR code with your iPhone camera". Steps can change, so check them on your own phone.

From an AI chat to a printed sign: ask, paste, make the code, put it at the chair.
From an AI chat to a printed sign: ask, paste, make the code, put it at the chair.

Where to put the sign

Put the code where the client looks while waiting and while sitting in the chair. Dark code on a light background, away from glare from the mirror lights, is easier to scan than a code on a glossy or patterned sign.

Under the code write three words, such as "Scan for prices", so people know what it opens. Add the plain link in small print for anyone whose phone does not scan.

At the mirror a sign with a QR code. On the phone, the same price list as a normal web page.
At the mirror a sign with a QR code. On the phone, the same price list as a normal web page.

The reason to use a link is the day a price moves.

A price printed on a sheet needs reprinting. A QR code to a page is printed once.
A price printed on a sheet needs reprinting. A QR code to a page is printed once.
Way to show prices When a price changes What the client needs
Printed sheet in a frame Edit, print, swap every copy Nothing, but they must be at the chair
PDF sent as a file New file, sent again A way to open the file
Link behind a QR code Edit the page, same link A phone that scans QR codes
The same link in a message Edit the page, same link A browser

For a longer look at sending lists to customers, see send a price list to customers.

Let clients add up their visit

A second page can do a little more. The client ticks the services they want and the page adds up the price and the time. It runs inside the page, so it works in a share link.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Corner Cut Barbers - Build my visit</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui, sans-serif; background: #f3f1ed; color: #1f2430; }
  header { background: #1f2430; color: #fff; padding: 16px 18px; }
  header h1 { margin: 0; font-size: 20px; }
  header p { margin: 2px 0 0; font-size: 13px; color: #c9ced9; }
  main { max-width: 560px; margin: 0 auto; padding: 14px 14px 120px; }
  label.item { display: flex; align-items: center; gap: 12px; background: #fff; border: 2px solid transparent; border-radius: 12px; padding: 12px 14px; margin-bottom: 8px; cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,.08); }
  label.item:has(input:checked) { border-color: #166534; background: #f0fdf4; }
  label.item input { width: 22px; height: 22px; accent-color: #166534; flex: none; }
  .t { flex: 1; font-weight: 600; }
  .t small { display: block; font-weight: 400; color: #5b6272; font-size: 13px; }
  .p { font-weight: 700; font-variant-numeric: tabular-nums; }
  .bar { position: fixed; left: 0; right: 0; bottom: 0; background: #1f2430; color: #fff; padding: 12px 18px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
  .bar .sum { font-size: 13px; color: #c9ced9; line-height: 1.4; }
  .bar .sum b { display: block; color: #fff; font-size: 22px; font-variant-numeric: tabular-nums; }
  .bar button { border: 0; border-radius: 10px; padding: 11px 14px; font: inherit; font-weight: 700; background: #fff; color: #1f2430; cursor: pointer; }
  #list { margin: 0 0 10px; padding: 0; list-style: none; font-size: 14px; color: #3a4150; }
</style>
</head>
<body>
<header>
  <h1>Build my visit</h1>
  <p>Tick what you want. Example prices.</p>
</header>
<main>
  <label class="item"><input type="checkbox" data-name="Classic cut" data-price="25" data-min="30"><span class="t">Classic cut<small>30 min</small></span><span class="p">$25</span></label>
  <label class="item"><input type="checkbox" data-name="Skin fade" data-price="30" data-min="40"><span class="t">Skin fade<small>40 min</small></span><span class="p">$30</span></label>
  <label class="item"><input type="checkbox" data-name="Beard trim" data-price="12" data-min="15"><span class="t">Beard trim<small>15 min</small></span><span class="p">$12</span></label>
  <label class="item"><input type="checkbox" data-name="Hot towel shave" data-price="28" data-min="30"><span class="t">Hot towel shave<small>30 min</small></span><span class="p">$28</span></label>
  <label class="item"><input type="checkbox" data-name="Neck and line-up" data-price="8" data-min="10"><span class="t">Neck and line-up<small>10 min</small></span><span class="p">$8</span></label>
  <ul id="list"></ul>
</main>
<div class="bar">
  <div class="sum"><b id="total">$0</b><span id="mins">0 min</span></div>
  <button type="button" id="clear">Clear</button>
</div>

<script>
  const boxes = document.querySelectorAll('input[type=checkbox]');
  const totalEl = document.getElementById('total');
  const minsEl = document.getElementById('mins');
  const listEl = document.getElementById('list');

  function update() {
    let total = 0, mins = 0;
    const names = [];
    boxes.forEach((b) => {
      if (b.checked) {
        total += Number(b.dataset.price);
        mins += Number(b.dataset.min);
        names.push(b.dataset.name);
      }
    });
    totalEl.textContent = '$' + total;
    minsEl.textContent = mins + ' min';
    listEl.innerHTML = '';
    names.forEach((n) => {
      const li = document.createElement('li');
      li.textContent = n;
      listEl.appendChild(li);
    });
  }

  boxes.forEach((b) => b.addEventListener('change', update));
  document.getElementById('clear').addEventListener('click', () => {
    boxes.forEach((b) => { b.checked = false; });
    update();
  });
</script>
</body>
</html>
Tick services to see the total price and minutes. The Clear button resets it. Example prices.

The ticks a client makes are not saved, and the owner's page does not change. Each person starts from a clean list. Ask the AI to "add checkboxes that total the price and minutes".

When it does not work

What you see Cause Fix
The camera shows nothing at the sign The code is small, shiny or at a steep angle, or scanning is off in the camera Scan from the chair, reprint bigger on a matte sheet, and check the camera settings
A price on the page is wrong The AI changed or invented it Compare with your own list and ask the AI to correct that line
The sign opens a different page than the one you edit The code was made from another link Make the code again from the share link of the page you edit
The page looks cramped on a phone The layout was made for a wide screen Ask for a mobile-first layout
No picture shows Images from other sites are blocked Use an inline drawing or leave the picture out
A booking form does nothing Sending a form to a server is blocked Write your phone number on the page

Questions people ask

Do I have to reprint the QR code when I change a price?

No, as long as you edit the same page. The code holds the address of the page, not the prices. In NOS, editing the code of a page keeps the same share link, so the sign on the wall keeps working and the next scan shows the new prices.

Can clients book an appointment from this page?

Not by sending a form. NOS blocks a form that posts to a server. Write your phone number on the page, or the way you take bookings today, and let the client use that. The page is for showing services and prices.

Can I see who opened the price list?

No. NOS gives you a page that anyone with the link can open, with no account, and it has no count of who opened it. If you need to know how many people scan the sign, you will have to count another way.

Can a client change the prices on the page?

No. A share link opens a page that the visitor can read but cannot edit. Only you change it, from your own document in NOS.

What if a client has an old phone or no camera scanning?

Put the plain link in small print under the code, or on a card at the desk, so it can be typed or sent in a message. The same link opens in a browser, so a client without QR scanning can still see the list.

Keep reading