A celebration of life website can be one page: the name, the day and time, the place, and the stories people want to read.
People ask which free or cheap builder suits a simple one-page site. Here you can skip it: an AI chat writes the page, and NOS turns it into a link.
Guests may be older, far away, or reading on a phone in a hurry. A link they open without signing up suits them. Here is a finished page to copy.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Celebrating the life of Peggy Hollis</title>
<style>
* { box-sizing: border-box; }
body { margin: 0; background: #f6f3ee; color: #2b2a28; font-family: Georgia, "Times New Roman", serif; line-height: 1.6; font-size: 1.05rem; }
.wrap { max-width: 560px; margin: 0 auto; padding: 0 18px 40px; }
header { text-align: center; padding: 36px 0 18px; }
header svg { width: 72px; height: 72px; }
.kicker { margin: 8px 0 0; font: 700 .76rem system-ui, sans-serif; letter-spacing: 1.6px; text-transform: uppercase; color: #5f7a5a; }
h1 { font-size: 2.1rem; font-weight: 400; margin: 4px 0 2px; }
.years { margin: 0; color: #6d6a64; font-style: italic; }
.when { margin: 16px 0 2px; font-size: 1.25rem; }
.count { margin: 0; font: 600 .86rem system-ui, sans-serif; color: #5f7a5a; }
section { background: #fff; border-radius: 12px; padding: 16px 18px; margin-top: 14px; box-shadow: 0 1px 4px rgba(40, 40, 30, .08); }
h2 { font: 700 .78rem system-ui, sans-serif; letter-spacing: 1.4px; text-transform: uppercase; color: #5f7a5a; margin: 0 0 8px; }
.venue { font-size: 1.15rem; margin: 0; }
.addr { margin: 2px 0 12px; color: #6d6a64; }
.btn { display: inline-block; padding: 12px 18px; border-radius: 8px; background: #4d6a49; color: #fff; text-decoration: none; font: 600 .98rem system-ui, sans-serif; }
ul.times { list-style: none; margin: 0; padding: 0; }
ul.times li { display: flex; gap: 14px; padding: 7px 0; border-top: 1px solid #ece8e0; }
ul.times li:first-child { border-top: 0; }
ul.times b { flex: 0 0 76px; font: 700 .95rem system-ui, sans-serif; }
blockquote { margin: 0; padding: 10px 0 10px 14px; border-left: 3px solid #b9c9b5; }
blockquote + blockquote { margin-top: 10px; }
blockquote p { margin: 0 0 4px; }
cite { font: 600 .88rem system-ui, sans-serif; color: #6d6a64; font-style: normal; }
.ask { margin: 12px 0 0; color: #6d6a64; font-size: .95rem; }
details { border-top: 1px solid #ece8e0; padding: 9px 0; }
details:first-of-type { border-top: 0; }
summary { cursor: pointer; font-weight: 700; }
details p { margin: 6px 0 0; color: #4a4843; }
footer { text-align: center; margin-top: 22px; color: #6d6a64; font-size: .95rem; }
</style>
</head>
<body>
<div class="wrap">
<header>
<svg viewBox="0 0 72 72" aria-hidden="true">
<circle cx="36" cy="36" r="34" fill="#e4ebe1"/>
<path d="M36 54 C36 40 36 32 36 20" stroke="#4d6a49" stroke-width="3" fill="none" stroke-linecap="round"/>
<path d="M36 44 C26 44 20 38 20 30 C30 30 36 36 36 44Z" fill="#7d9b78"/>
<path d="M36 36 C46 36 52 30 52 22 C42 22 36 28 36 36Z" fill="#9db898"/>
</svg>
<p class="kicker">A celebration of life</p>
<h1>Peggy Hollis</h1>
<p class="years">1941 – 2026</p>
<p class="when"><time datetime="2026-11-14T14:00">Saturday 14 November 2026, 2:00 pm</time></p>
<p class="count" id="count"></p>
</header>
<section>
<h2>Where</h2>
<p class="venue">Ashby Green Village Hall</p>
<p class="addr">12 Meadow Lane, Ashby Green</p>
<a class="btn" href="https://www.google.com/maps/search/?api=1&query=Ashby+Green+Village+Hall+12+Meadow+Lane" target="_blank" rel="noopener">Open in maps</a>
</section>
<section>
<h2>The afternoon</h2>
<ul class="times">
<li><b>2:00 pm</b> Welcome and a song</li>
<li><b>2:15 pm</b> Words from the family</li>
<li><b>2:45 pm</b> Stories from anyone who would like to share one</li>
<li><b>3:30 pm</b> Tea, sandwiches and Peggy’s lemon cake</li>
<li><b>4:30 pm</b> Close</li>
</ul>
</section>
<section>
<h2>Stories</h2>
<blockquote>
<p>She kept a jar of toffees by the door and always said they were for the postman. The postman never got one.</p>
<cite>Marcus, neighbour</cite>
</blockquote>
<blockquote>
<p>Peggy taught me to drive in a hall car park on Sundays. She never once raised her voice, only her eyebrows.</p>
<cite>Eleni, granddaughter</cite>
</blockquote>
<p class="ask">Have a story? Message Dan before 11 November and he will add it here.</p>
</section>
<section>
<h2>Good to know</h2>
<details open>
<summary>What to wear</summary>
<p>Peggy loved colour. Wear something bright if you like. Black is not required.</p>
</details>
<details>
<summary>Flowers</summary>
<p>The family asks for no flowers. A donation to the Ashby Green Garden Club would please her.</p>
</details>
<details>
<summary>Parking and access</summary>
<p>Parking is behind the hall. The entrance is step-free, and there are seats at the front.</p>
</details>
<details>
<summary>Children</summary>
<p>Children are very welcome.</p>
</details>
</section>
<footer>With love, from Dan, Eleni and the family.</footer>
</div>
<script>
// Days left until the day (dates in this example are made up)
const day = new Date(2026, 10, 14);
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const left = Math.round((day - today) / 86400000);
const el = document.getElementById('count');
el.textContent = left > 1 ? left + ' days to go' : left === 1 ? 'Tomorrow' : left === 0 ? 'Today' : 'Thank you for coming';
</script>
</body>
</html>
The names, hall and times are made up. Swap in yours. The line under the date is a small script that counts days, and it runs on the shared link too.
What goes on the page
Most guests will open the link on a phone, so the page is one column, and the answer to "when and where" sits on the first screen.

Four blocks cover it: the name and time, the place with a map button, the stories, and a few notes. The time sits in an HTML time element, which MDN describes as a way to give a date in a form machines can read.
The notes use the native details element. It shows a heading that opens and closes the text under it, and MDN documents that it needs no JavaScript. Dress, flowers, parking and children each get a heading.
For a page built around one event, see event landing page.
Make it with AI
Paste this prompt into ChatGPT, Claude or Gemini after replacing the details in capitals.
Write one self-contained HTML file for a celebration of life page.
In memory of: FULL NAME, YEARS. Host: NAME, relationship.
Date: DAY, DATE, YEAR, TIME. Venue: NAME, FULL ADDRESS.
Order of the afternoon: TIME - WHAT HAPPENS (one line each).
Stories: paste 2-3 short ones with who sent each.
Notes: what to wear, flowers or donations, parking, children.
Tone: calm, warm, plain. One column, readable on a phone, with the
viewport meta tag. Put the date and time at the top. Under the venue,
add a button that links to a Google Maps search URL for the address.
Show notes with details and summary. No external images, no iframes,
no libraries. Decorate with CSS or inline SVG only. Return only the code.
Then check the result yourself. An AI can change a fact without any sign.
- The name is spelled exactly as the family writes it.
- The day of the week matches the date.
- Every time and the address are as you wrote them.
- The map button opens the right place when you tap it.
- Each story is word for word what its author sent, with the right name.
- No placeholder text such as "Your venue here" is left.
Send it as a link
Paste the finished code into a NOS document and choose Create share link. The page renders as written, scripts included. HTML to link walks through it.

Anyone with the link opens the page in a browser, on a phone too, with no account. They cannot edit it. When a time changes, edit the code and the same link shows the new version.
A file is a copy, and a picture of the invitation is a copy too. A link is the page itself. Why a file often fails on a phone is in opening an HTML file on a phone.
Think before you post the link in a public place. NOS has no password, so anyone who gets the link can read the page. Leave off a private home address and say where to find that in a message instead.
To print the link on the order of service, turn it into a QR code. QR code link shows how.
Ways to share the details compared
| Way | Guest opens it | A change reaches guests |
|---|---|---|
| Printed notice only | On paper | Only by contacting people |
| Picture in a chat | In the chat | Only if you send a new one |
| HTML file as attachment | Depends on the phone and the app | Only if you send it again |
| NOS share link | In the browser, no account | Yes, the same link updates |
| Google Sites page | In the browser, once published | See Google's help |
Google Sites is a separate tool with its own editor. As of October 2026, Google's help says you publish a site with a web address and choose whether it is restricted to people you invite or public.
The map button uses a search URL that Google documents. It needs no API key, and on Android and iOS it opens the Maps app when that is installed and a browser when it is not.
Stories guests send you
A page for reading is also a page for remembering. Guests cannot type on it, so they send you a story and you place it on the page.

Here is a page that holds stories only. Filter by who wrote them, read one at random, or make the text larger for readers who want it.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Stories about Peggy</title>
<style>
* { box-sizing: border-box; }
body { margin: 0; padding: 16px; background: #f6f3ee; color: #2b2a28; font-family: Georgia, "Times New Roman", serif; line-height: 1.55; }
.wrap { max-width: 560px; margin: 0 auto; }
h1 { font-size: 1.5rem; font-weight: 400; margin: 0 0 2px; }
.sub { margin: 0 0 14px; color: #6d6a64; font-style: italic; }
.bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
button { font: 600 .9rem system-ui, sans-serif; padding: 10px 14px; border-radius: 8px; border: 1px solid #b9c9b5; background: #fff; color: #3f5a3b; cursor: pointer; }
button[aria-pressed="true"] { background: #4d6a49; color: #fff; border-color: #4d6a49; }
.tools { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
#stories { font-size: 1.05rem; }
article { background: #fff; border-radius: 12px; padding: 14px 16px; margin-bottom: 10px; box-shadow: 0 1px 4px rgba(40, 40, 30, .08); border: 2px solid transparent; }
article[hidden] { display: none; }
article.pick { border-color: #7d9b78; }
article p { margin: 0 0 6px; }
cite { font: 600 .88rem system-ui, sans-serif; font-style: normal; color: #6d6a64; }
.none { color: #6d6a64; }
</style>
</head>
<body>
<div class="wrap">
<h1>Stories about Peggy</h1>
<p class="sub">Sent in by family, friends and neighbours.</p>
<div class="bar" id="filters">
<button data-group="all" aria-pressed="true">All</button>
<button data-group="family" aria-pressed="false">Family</button>
<button data-group="friends" aria-pressed="false">Friends</button>
<button data-group="neighbours" aria-pressed="false">Neighbours</button>
</div>
<div class="tools">
<button id="random">Read one at random</button>
<button id="big" aria-pressed="false">Larger text</button>
</div>
<div id="stories">
<article data-group="neighbours"><p>She kept a jar of toffees by the door and always said they were for the postman. The postman never got one.</p><cite>Marcus, neighbour</cite></article>
<article data-group="family"><p>Peggy taught me to drive in a hall car park on Sundays. She never once raised her voice, only her eyebrows.</p><cite>Eleni, granddaughter</cite></article>
<article data-group="friends"><p>Every spring she gave away seedlings from her windowsill. Half the gardens on our road began in her kitchen.</p><cite>Roz, friend from the garden club</cite></article>
<article data-group="family"><p>She answered the phone with the full number, even for family. We still do it as a joke.</p><cite>Dan, son</cite></article>
<article data-group="friends"><p>She beat me at cards for thirty years and never once let me forget it. I would give anything for one more hand.</p><cite>Walter, friend</cite></article>
<article data-group="neighbours"><p>When our power went out, she appeared with a flask of soup and a torch and stayed to play board games.</p><cite>The Okafor family, next door</cite></article>
<p class="none" id="none" hidden>No stories in this group yet.</p>
</div>
</div>
<script>
const items = [...document.querySelectorAll('#stories article')];
const filters = [...document.querySelectorAll('#filters button')];
const none = document.getElementById('none');
const big = document.getElementById('big');
function show(group) {
// Show one group, or all of them
items.forEach((a) => {
a.classList.remove('pick');
a.hidden = group !== 'all' && a.dataset.group !== group;
});
filters.forEach((b) => b.setAttribute('aria-pressed', String(b.dataset.group === group)));
none.hidden = items.some((a) => !a.hidden);
}
filters.forEach((b) => b.addEventListener('click', () => show(b.dataset.group)));
document.getElementById('random').addEventListener('click', () => {
show('all');
const a = items[Math.floor(Math.random() * items.length)];
items.forEach((x) => x.classList.toggle('pick', x === a));
a.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
});
big.addEventListener('click', () => {
const on = big.getAttribute('aria-pressed') !== 'true';
big.setAttribute('aria-pressed', String(on));
document.getElementById('stories').style.fontSize = on ? '1.35rem' : '1.05rem';
});
</script>
</body>
</html>
Each story is one block with its text and a name. Ask the AI to add a story in the same style, and read it before you save. For sending the page out in the first place, see invitation to link.
When it does not work
| What you see | Cause | Fix |
|---|---|---|
| The page looks tiny on a phone | The viewport meta tag is missing | Ask the AI to add it, see viewport meta tag |
| A photo is missing | The image is hosted on another site, which NOS blocks | Use CSS or inline SVG |
| The map area is empty | An embedded map uses an iframe, which NOS blocks | Replace it with a button that links to the map |
| A guest cannot add a story | A visitor's changes are not saved, and forms cannot send to a server | Ask guests to message you |
| A guest still sees the old time | They have the old page open | Ask them to reload the link |
| The AI changed a name or a date | Generated text can drift from your input | Read every fact before sharing |