A travel itinerary template you can send to the whole group

One page, one block per day, a Map link on every stop. Copy the example, fill it with your trip using an AI chat, and send everyone the same link.

A travel itinerary template that works for a group is a single web page: a block for each day, the first time of the day in large type, and a Map link on every place.

If you are looking for a way to share a trip with friends, a page with one address does it. Everyone opens the same version, and one edit reaches all of them.

Here is a three-day example with fictional plans. Switch between the days, and try the buttons on a phone-sized window too.

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>Porto long weekend</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .wrap { max-width: 560px; margin: 0 auto; padding: 16px 14px 28px; }
  h1 { font-size: 22px; margin: 0 0 4px; }
  .meta { font-size: 14px; color: #4b5563; margin: 0 0 4px; }
  .tz { display: inline-block; font-size: 13px; background: #e8f0fe; color: #1e40af; border-radius: 6px; padding: 3px 8px; margin: 6px 0 14px; }
  .tabs { display: flex; gap: 8px; margin-bottom: 14px; }
  .tabs button { flex: 1; font: 600 15px system-ui, sans-serif; padding: 10px 6px; border: 1px solid #d5d9e0; border-radius: 10px; background: #fff; color: #374151; cursor: pointer; }
  .tabs button[aria-selected="true"] { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
  .day { display: none; }
  .day.on { display: block; }
  .day h2 { font-size: 16px; margin: 0 0 10px; color: #374151; }
  .stop { background: #fff; border: 1px solid #e1e4ea; border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
  .stop .time { font-size: 20px; font-weight: 700; }
  .stop:first-of-type .time { font-size: 28px; color: #1d4ed8; }
  .stop .what { font-size: 16px; font-weight: 600; margin: 2px 0; }
  .stop .note { font-size: 14px; color: #4b5563; margin: 0 0 8px; }
  .links a { display: inline-block; font-size: 14px; font-weight: 600; text-decoration: none; padding: 8px 12px; border-radius: 8px; margin-right: 6px; background: #eef2ff; color: #1d4ed8; }
  .links a.dir { background: #ecfdf3; color: #0f5132; }
  .chg { display: inline-block; font-size: 12px; font-weight: 700; background: #fff1e0; color: #9a3412; border-radius: 5px; padding: 2px 6px; margin-left: 6px; vertical-align: middle; }
  .foot { font-size: 13px; color: #6b7280; margin-top: 14px; }
</style>
</head>
<body>
<div class="wrap">
  <h1>Porto long weekend</h1>
  <p class="meta">4 friends &middot; 12&ndash;14 June</p>
  <span class="tz">All times are Porto local time</span>

  <div class="tabs" role="tablist" id="tabs">
    <button role="tab" aria-selected="true" data-day="d1">Day 1</button>
    <button role="tab" aria-selected="false" data-day="d2">Day 2</button>
    <button role="tab" aria-selected="false" data-day="d3">Day 3</button>
  </div>

  <section class="day on" id="d1">
    <h2>Arrive and walk the river</h2>
    <div class="stop">
      <div class="time">10:40</div>
      <div class="what">Land at Porto Airport</div>
      <p class="note">Meet at arrivals. Buy metro tickets together.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Porto+Airport" target="_blank" rel="noopener">Map</a><a class="dir" href="https://www.google.com/maps/dir/?api=1&amp;destination=Rua+das+Flores+Porto&amp;travelmode=transit" target="_blank" rel="noopener">Directions to the flat</a></div>
    </div>
    <div class="stop">
      <div class="time">14:00</div>
      <div class="what">Walk down to the river</div>
      <p class="note">Easy, flat along the water. Coffee stop on the way.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Ribeira+Porto" target="_blank" rel="noopener">Map</a><a class="dir" href="https://www.google.com/maps/dir/?api=1&amp;destination=Ribeira+Porto&amp;travelmode=walking" target="_blank" rel="noopener">Walking directions</a></div>
    </div>
    <div class="stop">
      <div class="time">17:30</div>
      <div class="what">Cross the Dom Lu&iacute;s I bridge</div>
      <p class="note">Sunset photos from the upper deck.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Dom+Luis+I+Bridge+Porto" target="_blank" rel="noopener">Map</a></div>
    </div>
    <div class="stop">
      <div class="time">20:30 <span class="chg">changed: was 20:00</span></div>
      <div class="what">Dinner near Pra&ccedil;a da Ribeira</div>
      <p class="note">Table for four. Booking details are on the pre-trip page.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Praca+da+Ribeira+Porto" target="_blank" rel="noopener">Map</a></div>
    </div>
  </section>

  <section class="day" id="d2">
    <h2>Old town and viewpoints</h2>
    <div class="stop">
      <div class="time">09:30</div>
      <div class="what">Breakfast near S&atilde;o Bento station</div>
      <p class="note">Then look at the tile panels in the main hall.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Sao+Bento+Station+Porto" target="_blank" rel="noopener">Map</a><a class="dir" href="https://www.google.com/maps/dir/?api=1&amp;destination=Sao+Bento+Station+Porto&amp;travelmode=walking" target="_blank" rel="noopener">Walking directions</a></div>
    </div>
    <div class="stop">
      <div class="time">11:30</div>
      <div class="what">Cathedral and its terrace</div>
      <p class="note">Uphill from the station. Allow time for the view.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Porto+Cathedral" target="_blank" rel="noopener">Map</a><a class="dir" href="https://www.google.com/maps/dir/?api=1&amp;destination=Porto+Cathedral&amp;travelmode=walking" target="_blank" rel="noopener">Walking directions</a></div>
    </div>
    <div class="stop">
      <div class="time">14:00</div>
      <div class="what">Lunch at the Bolh&atilde;o market</div>
      <p class="note">Split into pairs, meet back at the entrance at 15:00.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Bolhao+Market+Porto" target="_blank" rel="noopener">Map</a></div>
    </div>
    <div class="stop">
      <div class="time">16:30</div>
      <div class="what">Free time</div>
      <p class="note">Shops, a rest at the flat, or the gardens by the river.</p>
    </div>
  </section>

  <section class="day" id="d3">
    <h2>Beach and flight home</h2>
    <div class="stop">
      <div class="time">09:00</div>
      <div class="what">Check out and leave bags</div>
      <p class="note">Keys go in the lockbox. Bags stay with the host until 15:00.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Rua+das+Flores+Porto" target="_blank" rel="noopener">Map</a></div>
    </div>
    <div class="stop">
      <div class="time">10:15</div>
      <div class="what">Metro to the beach</div>
      <p class="note">Lunch by the sea afterwards.</p>
      <div class="links"><a href="https://www.google.com/maps/search/?api=1&amp;query=Matosinhos+Beach" target="_blank" rel="noopener">Map</a><a class="dir" href="https://www.google.com/maps/dir/?api=1&amp;destination=Matosinhos+Beach&amp;travelmode=transit" target="_blank" rel="noopener">Transit directions</a></div>
    </div>
    <div class="stop">
      <div class="time">15:30</div>
      <div class="what">Collect bags, go to the airport</div>
      <p class="note">Flight at 18:15. Be at the airport by 16:00.</p>
      <div class="links"><a href="https://www.google.com/maps/dir/?api=1&amp;destination=Porto+Airport&amp;travelmode=transit" target="_blank" rel="noopener" class="dir">Transit directions</a></div>
    </div>
  </section>

  <p class="foot">Map and Directions buttons are ordinary links to Google Maps. Directions links have no start point, so Maps uses your location if it can.</p>
</div>

<script>
  const tabs = document.querySelectorAll('#tabs button');
  const days = document.querySelectorAll('.day');

  tabs.forEach((btn) => {
    btn.addEventListener('click', () => {
      tabs.forEach((b) => b.setAttribute('aria-selected', String(b === btn)));
      days.forEach((d) => d.classList.toggle('on', d.id === btn.dataset.day));
    });
  });
</script>
</body>
</html>
A three-day itinerary. The day buttons, the changed tag and the Map links are all in the page.

The map buttons point to real Google Maps addresses. This example box is sandboxed and may not open them, so test the buttons on your own shared link instead.

What each day needs

People rarely read an itinerary from top to bottom. They open it to answer one question: what is next, and where? Build each day around that.

What the group sees on a phone, and why each part is there.
What the group sees on a phone, and why each part is there.
  • The first time and place, in large type. Everything else on the day can be smaller.
  • One line naming the time zone. Say once which city the times belong to.
  • A Map link on every place. Describing directions in words is slower than a tap.
  • A short note per stop. What to bring, who is meeting whom, or what is booked.
  • A mark on anything that changed. People can see what moved since they last looked.

Itinerary link goes deeper on what belongs at the top of a day and what belongs nowhere.

Make it with AI

You do not have to write the HTML. Paste this prompt into ChatGPT, Claude or Gemini, replace the square brackets with your trip, and ask for the full file.

Write one self-contained HTML file for a day-by-day travel itinerary.

Trip: [city], [number] days, [number] friends, [dates].
Plan: Day 1: [places and times]. Day 2: [places and times].

Rules:
- One section per day, shown one at a time with buttons for Day 1, Day 2, and so on.
- Each stop shows the local time in large type, the place name and a one-line note.
- One line under the title says which city's local time is used.
- Give every place a Map link like this:
  https://www.google.com/maps/search/?api=1&query=PLACE+CITY
- For a walk or ride, add a Directions link like this:
  https://www.google.com/maps/dir/?api=1&destination=PLACE+CITY&travelmode=walking
- Do not embed maps and do not use iframes.
- No external images, fonts or scripts. Inline CSS and a little inline JavaScript only.
- It must read well on a phone 390 pixels wide, with buttons at least 40 pixels tall.
- No forms that send data anywhere.

Then check the result before you send it:

  • Open every Map link. A vague place name can land on the wrong place.
  • Check times and distances. An AI chat can pack a day with stops that cannot be reached in the time given.
  • Check that each place exists and is open on the day you plan to go, using the place's own website.
  • Look for map frames or pictures from other sites. Ask for a rewrite without them.
  • Narrow the window to phone width and tap the day buttons.
From the AI chat to an address you can send to the group.
From the AI chat to an address you can send to the group.
  1. Copy the HTML the chat wrote.
  2. Paste it into a NOS document. The page shows as written, with its scripts running, so the day buttons work.
  3. Choose Create share link.
  4. Send the address in your group chat or by email.

Whoever opens the link sees the finished page in a browser, on a phone or a computer. They do not need an account, and they cannot edit the page. HTML to link walks through the steps with screenshots.

When the plan changes, edit the code and the same link shows the new version. Nobody has to find the latest copy in a message thread.

When someone taps a Map link on a shared page, NOS first shows a notice, Leave for another site?, with the full address. They choose Open link and Maps opens in a new tab. That was how NOS handled outside links as of October 2026.

An HTML file sent as an attachment is a different case. It can open as plain code on a phone, which is covered in opening an HTML file on a phone.

The usual first idea is to put a Google Map into each day. That needs an iframe, and NOS blocks iframes, so the frame stays empty.

Left: an embedded map frame stays blank. Right: a link opens Maps.
Left: an embedded map frame stays blank. Right: a link opens Maps.

A link needs no frame. Google documents two link shapes. As of October 2026, they look like this:

https://www.google.com/maps/search/?api=1&query=Sao+Bento+Station+Porto
https://www.google.com/maps/dir/?api=1&destination=Sao+Bento+Station+Porto&travelmode=walking

The first shows a place. The second starts directions. Google says the api=1 part is required in every link, and that all other parts are ignored without it.

Part What it does
query A place name, an address, or latitude and longitude separated by a comma
destination Where the route ends, in the same forms
origin Where it starts. Leave it out and Maps uses the device location if it can
travelmode driving, walking, bicycling, two-wheeler or transit

Google also asks that the address is URL-encoded. In plain terms, spaces become plus signs, as in the examples above. On a phone, the link opens the Google Maps app if it is installed. Linking to a map location covers other map apps.

A pre-trip page for bookings and packing

Times and places are half of the job. The other half is the reference numbers and the packing list. A second small page keeps them together, so the day-by-day page stays clean.

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>Before we go: Porto</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .wrap { max-width: 560px; margin: 0 auto; padding: 16px 14px 28px; }
  h1 { font-size: 22px; margin: 0 0 4px; }
  h2 { font-size: 16px; margin: 22px 0 8px; }
  .sub { font-size: 14px; color: #4b5563; margin: 0; }
  .card { background: #fff; border: 1px solid #e1e4ea; border-radius: 12px; overflow: hidden; }
  .book { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; padding: 11px 14px; border-top: 1px solid #eef0f4; }
  .book:first-child { border-top: 0; }
  .book b { font-size: 15px; }
  .book .when { font-size: 14px; color: #4b5563; }
  .book .ref { grid-row: 1 / span 2; grid-column: 2; align-self: center; font: 600 13px ui-monospace, Consolas, monospace; background: #eef1f5; border-radius: 6px; padding: 4px 8px; }
  .prog { font-size: 14px; color: #4b5563; margin: 0 0 8px; }
  .list { list-style: none; margin: 0; padding: 0; }
  .list li { border-top: 1px solid #eef0f4; }
  .list li:first-child { border-top: 0; }
  .list label { display: flex; align-items: center; gap: 12px; padding: 12px 14px; font-size: 16px; cursor: pointer; }
  .list input[type="checkbox"] { width: 22px; height: 22px; flex: none; }
  .list li.done label span:not(.who) { color: #9ca3af; text-decoration: line-through; }
  .who { margin-left: auto; font-size: 13px; color: #6b7280; }
  form { display: flex; gap: 8px; margin-top: 10px; }
  form input { flex: 1; min-width: 0; font: 16px system-ui, sans-serif; padding: 10px 12px; border: 1px solid #d5d9e0; border-radius: 10px; }
  form button { font: 600 15px system-ui, sans-serif; padding: 10px 14px; border: 0; border-radius: 10px; background: #1d4ed8; color: #fff; cursor: pointer; }
  .tip { font-size: 13px; color: #6b7280; margin-top: 10px; }
</style>
</head>
<body>
<div class="wrap">
  <h1>Before we go</h1>
  <p class="sub">Porto long weekend &middot; 12&ndash;14 June &middot; booking codes below are made up</p>

  <h2>Bookings</h2>
  <div class="card">
    <div class="book"><b>Flights out</b><span class="when">Day 1, lands 10:40</span><span class="ref">ZX4Q7P</span></div>
    <div class="book"><b>Flat, 2 nights</b><span class="when">Check-in from 12:30, check-out 09:00</span><span class="ref">FL-20418</span></div>
    <div class="book"><b>Dinner for four</b><span class="when">Day 1, 20:30</span><span class="ref">TBL-77</span></div>
    <div class="book"><b>Flights home</b><span class="when">Day 3, departs 18:15</span><span class="ref">ZX9M2K</span></div>
  </div>

  <h2>Who brings what</h2>
  <p class="prog" id="prog"></p>
  <div class="card">
    <ul class="list" id="list">
      <li><label><input type="checkbox"><span>Passports or ID cards</span><span class="who">everyone</span></label></li>
      <li><label><input type="checkbox"><span>Phone charger and plug adapter</span><span class="who">everyone</span></label></li>
      <li><label><input type="checkbox"><span>Printed flat address</span><span class="who">Mira</span></label></li>
      <li><label><input type="checkbox"><span>Rain jackets</span><span class="who">everyone</span></label></li>
      <li><label><input type="checkbox"><span>Cash for small shops</span><span class="who">Jonas</span></label></li>
    </ul>
  </div>

  <form id="add">
    <input id="newItem" type="text" placeholder="Add an item" aria-label="Add an item" autocomplete="off">
    <button type="submit">Add</button>
  </form>
  <p class="tip">Tick items off as you pack, or add one of your own.</p>
</div>

<script>
  const list = document.getElementById('list');
  const prog = document.getElementById('prog');

  function update() {
    const boxes = list.querySelectorAll('input[type="checkbox"]');
    const done = list.querySelectorAll('input:checked').length;
    prog.textContent = done + ' of ' + boxes.length + ' packed';
    boxes.forEach((b) => b.closest('li').classList.toggle('done', b.checked));
  }

  list.addEventListener('change', update);

  document.getElementById('add').addEventListener('submit', (e) => {
    e.preventDefault();  // keep it on the page, nothing is sent anywhere
    const input = document.getElementById('newItem');
    const text = input.value.trim();
    if (!text) return;
    const li = document.createElement('li');
    const label = document.createElement('label');
    const box = document.createElement('input');
    box.type = 'checkbox';
    const span = document.createElement('span');
    span.textContent = text;  // textContent keeps typed HTML from running
    label.append(box, span);
    li.append(label);
    list.append(li);
    input.value = '';
    update();
  });

  update();
</script>
</body>
</html>
Bookings with made-up codes, and a packing list with ticks. Try ticking items and adding one.

This page uses an ordinary checkbox list and a one-field form that adds a line. Nothing is sent anywhere, because the form is handled inside the page.

In NOS, ticks and added rows you make as the owner in View mode are saved. A visitor's changes are not saved. So this works as a checklist you keep for the group, not one the group fills in together.

Ways to share a trip plan

HTML file as an attachment Link to a shared page
What the group gets A copy of the file The page itself, at one address
After you change the plan Copies already sent stay as they were The same link shows the new version
How it opens The recipient opens the file in a browser In a browser, with no account
Map links Work once the file is open Work

When it does not work

What you see Cause Fix
A map frame is blank NOS blocks iframes Replace the frame with a Map link
A Map button does nothing in an example box Sandboxed frames silently block links that open a new tab Open the shared link in your browser and test there
Maps opens on the wrong place The query is too vague Add the city, or use the address or coordinates
Maps opens with an empty start box A Directions link has no origin and no device location is available Add an origin part, or let the phone share its location
The link opens in the browser, not the app The Maps app may not be installed Install the app, or use the page in the browser
Pictures or a map image are missing Images from other sites are blocked Use inline SVG or CSS, or leave them out
Friends do not see your ticks Only the owner's changes are saved Treat the checklist as your own, and tell them what is packed
Some people see old times They are holding an old attached copy Send the link instead, and edit the page there

If you plan trips often, keep the first page as your template. Replace the city, the days and the places, and send a new link each time. See also why links beat attachments.

Questions people ask

Which site can I use to share my trip with friends?

Any page that has its own address works. With NOS you paste the itinerary page, choose Create share link, and send the address. Friends open it in a browser on a phone or a computer, and they do not need an account.

Can I put a Google Map inside the page?

Not as a frame. NOS blocks iframes, so an embedded map stays blank. Use a Map link on each stop instead. Tapping it opens Google Maps with the place or the route.

Can my friends add their own ideas to the page?

No. Anyone with the link can open the page but cannot edit it. Ask for suggestions in your group chat and make the change yourself. The link stays the same, so everyone sees the update.

What happens to the link when the plan changes?

Edit the code in NOS and the same link shows the new version. Mark the changed stop on the page, for example with a small "changed" tag, so people notice it.

Keep reading