A free classroom website: one page, made with AI

A class site can be one HTML page: this week's schedule, the links families keep asking for, and how to reach you. An AI writes it, and a share link publishes it.

A free classroom website can be a single page. An AI writes it as one HTML file, you paste the file into NOS, and Create share link gives you an address. No site builder, no template to pick, no sign-in for families.

A teacher's blog post on Gemini says you can ask it for code and then "copy and paste it into a simple website builder". This guide covers what to do with that code when you do not have a builder or a school site.

Here is the kind of page you will end up with. Try the buttons.

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>Room 12 class site</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui, sans-serif; font-size: 17px; line-height: 1.5; color: #1f2a37; background: #f4f6f8; }
  header { background: #1f5f8b; color: #fff; padding: 22px 18px 18px; }
  header h1 { margin: 0 0 2px; font-size: 24px; }
  header p { margin: 0; font-size: 15px; opacity: .9; }
  main { max-width: 640px; margin: 0 auto; padding: 14px 14px 28px; }
  section { background: #fff; border-radius: 12px; padding: 16px; margin-top: 14px; box-shadow: 0 1px 3px rgba(0, 0, 0, .08); }
  h2 { margin: 0 0 10px; font-size: 19px; }
  .tabs { display: flex; gap: 8px; margin-bottom: 10px; }
  .tabs button { flex: 1; padding: 9px 6px; font: inherit; font-size: 15px; border: 2px solid #1f5f8b; border-radius: 8px; background: #fff; color: #1f5f8b; cursor: pointer; }
  .tabs button[aria-pressed="true"] { background: #1f5f8b; color: #fff; }
  .day { display: grid; grid-template-columns: 56px 1fr; gap: 10px; padding: 9px 10px; border-radius: 8px; border: 2px solid transparent; }
  .day + .day { margin-top: 4px; }
  .day b { color: #1f5f8b; }
  .day span { font-size: 15px; color: #4b5563; display: block; }
  .day.today { background: #fff6d6; border-color: #f0b400; }
  .day.today b::after { content: " today"; display: block; font-size: 12px; font-weight: 600; color: #8a6100; }
  .links a { display: block; padding: 13px 14px; margin-top: 8px; border-radius: 10px; background: #e8f2f9; color: #12527a; font-weight: 600; text-decoration: none; }
  .links a small { display: block; font-weight: 400; color: #4b5563; font-size: 14px; }
  .links a:first-of-type { margin-top: 0; }
  dl { margin: 0; display: grid; grid-template-columns: 110px 1fr; gap: 6px 10px; }
  dt { font-weight: 600; } dd { margin: 0; }
  @media (min-width: 500px) { .links { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .links h2 { grid-column: 1 / -1; margin-bottom: 2px; } .links a { margin-top: 0 !important; } }
  .note { font-size: 14px; color: #6b7280; margin-top: 10px; }
  @media (max-width: 420px) { dl { grid-template-columns: 1fr; gap: 0; } dd { margin-bottom: 8px; } }
</style>
</head>
<body>
<header>
  <h1>Room 12 &middot; Grade 5</h1>
  <p>Maple Brook Elementary &middot; Updated Sunday evening</p>
</header>
<main>
  <section>
    <h2>Schedule</h2>
    <div class="tabs">
      <button type="button" id="wk-this" aria-pressed="true">This week</button>
      <button type="button" id="wk-next" aria-pressed="false">Next week</button>
    </div>
    <div id="days"></div>
  </section>

  <section class="links">
    <h2>Links</h2>
    <a href="#">Reading log <small>Fill in 20 minutes a night</small></a>
    <a href="#">Math practice <small>Fractions, set 3</small></a>
    <a href="#">School calendar <small>Holidays and early dismissals</small></a>
    <a href="#">Library catalog <small>Search and reserve books</small></a>
  </section>

  <section>
    <h2>Contact</h2>
    <dl>
      <dt>Teacher</dt><dd>Ms. Alder</dd>
      <dt>Email</dt><dd>m.alder@maplebrook.example</dd>
      <dt>Office</dt><dd>Front office, 555-0142</dd>
      <dt>Reply time</dt><dd>Within one school day</dd>
    </dl>
    <p class="note">Demo links go nowhere. Replace each # with a real address.</p>
  </section>
</main>

<script>
  // Two weeks of schedule data; edit the text, keep the shape.
  const weeks = {
    this: [
      ['Mon', 'Reading groups', 'Bring your library book'],
      ['Tue', 'Math: fractions', 'Quiz on Thursday'],
      ['Wed', 'Science lab', 'Wear closed shoes'],
      ['Thu', 'Math quiz', 'Art in the afternoon'],
      ['Fri', 'Class meeting', 'Early dismissal at 1:30']
    ],
    next: [
      ['Mon', 'Writing workshop', 'Draft due Friday'],
      ['Tue', 'Math: decimals', 'New homework sheet'],
      ['Wed', 'Library visit', 'Return books first'],
      ['Thu', 'Science: plants', 'Bring one seed'],
      ['Fri', 'Field trip', 'Permission slip needed']
    ]
  };
  const names = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  const box = document.getElementById('days');
  const thisBtn = document.getElementById('wk-this');
  const nextBtn = document.getElementById('wk-next');

  function show(key) {
    const today = names[new Date().getDay()];
    box.innerHTML = '';
    weeks[key].forEach(([d, title, note]) => {
      const row = document.createElement('div');
      // Highlight today only on the current week
      row.className = 'day' + (key === 'this' && d === today ? ' today' : '');
      row.innerHTML = '<b>' + d + '</b><div>' + title + '<span>' + note + '</span></div>';
      box.appendChild(row);
    });
    thisBtn.setAttribute('aria-pressed', key === 'this');
    nextBtn.setAttribute('aria-pressed', key === 'next');
  }
  thisBtn.addEventListener('click', () => show('this'));
  nextBtn.addEventListener('click', () => show('next'));
  show('this');
</script>
</body>
</html>
A one-page class site: schedule with a this-week and next-week switch, links and contact details.

The links in the demo go nowhere on purpose. On your page each one points to a real address. Today's row is highlighted by a few lines of script, which runs on the shared page too.

What belongs on a one-page class site

Families open a class page for three things: what is happening, where to click, and who to ask. That is the whole page.

Three blocks on the page, and what stays off it.
Three blocks on the page, and what stays off it.
  • Schedule: this week and next week, one line per day, with the one thing a child must bring.
  • Links: large buttons for the reading log, practice sites and the school calendar.
  • Contact: office hours, how fast you reply, and your school email written out as text.

Anyone with the link can open a shared page, and it has no password. So leave out student names, photos and grades, and use your school address, not a personal one.

Make it with AI

Open the AI chat you already use, such as ChatGPT, Claude or Gemini. Paste this, then change the details to match your class.

Make a single-file HTML page that is the class website for a
5th-grade class (Room 12, Maple Brook Elementary). Use placeholder
names and addresses I can replace.
Sections in this order: a header with the class name and "Updated"
day; "Schedule" for Monday to Friday with a subject and one note per
day; "Links" as large buttons (reading log, math practice, school
calendar, library catalog); "Contact" with office hours, reply time,
and a school email address and phone number written out as text.
18px text, high contrast, one column, works on a phone.
No external images, fonts or scripts. No forms. No student names.
Return only the HTML.

Check the result before you copy it:

  • Every placeholder is replaced, including the dates and the email address.
  • Each link opens the right page. AI can invent web addresses, so click all of them.
  • The page has no student names, photos or home contact details.
  • Text is easy to read on a phone-sized window.

If something is off, say so in the same chat, for example "make the buttons bigger and move Contact to the top", and paste the new version. Writing a good one-page prompt goes deeper on layout.

Open a NOS document and paste the HTML in. The page renders right there and its scripts run, so test the buttons yourself. Then choose Create share link and copy the address.

From a chat to one address: ask, check, paste, share.
From a chat to one address: ask, check, paste, share.

Anyone with the address can open the page in a browser, on a phone too, with no account. They can read it but not edit it. Change the code next Sunday and the same link shows the new week. HTML to link walks through it.

As of October 2026, NOS's pricing page lists a Free plan with 3 live share links, and published pages on Free carry a NOS badge. A class site needs one link. Check the pricing page for what applies when you read this.

A new address only helps if people find it. Use the places your families already open.

Where How Source of the steps
Classroom Stream On the Stream page choose Announce something to your class, add a link, post Google's Post announcements page
Classroom Classwork Classwork, Create, Material, add a link, pick a topic Google's Add materials page
An assignment Under the attach options choose Link Google's Create an assignment page
Paper handout Turn the address into a printed code QR code link
Email or message Paste the address Any mail app

A Classwork material can sit under a topic, such as "Class info", so it stays easy to find after the Stream scrolls on. Classroom menus can change, and which attach options you see depends on your account type, as of October 2026.

What a parent sees after tapping the link on a phone.
What a parent sees after tapping the link on a phone.

A second page: homework due dates

A schedule is not the only thing worth publishing. Older students ask the same question each day: what is due? Here is a board with subject filters and a due label that counts down.

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>Period 3 homework board</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; font-size: 16px; line-height: 1.45; color: #1f2937; background: #eef1f4; }
  .wrap { max-width: 640px; margin: 0 auto; }
  h1 { margin: 0; font-size: 22px; }
  .sub { margin: 2px 0 12px; color: #4b5563; font-size: 14px; }
  .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
  .chips button { padding: 7px 13px; font: inherit; font-size: 14px; border: 1.5px solid #3b6e57; border-radius: 999px; background: #fff; color: #2d5a45; cursor: pointer; }
  .chips button[aria-pressed="true"] { background: #2d5a45; color: #fff; }
  ul { list-style: none; margin: 0; padding: 0; }
  li { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; align-items: center; background: #fff; border-radius: 10px; padding: 12px 14px; margin-bottom: 8px; border-left: 6px solid #9ca3af; box-shadow: 0 1px 3px rgba(0, 0, 0, .07); }
  li.math { border-left-color: #2563eb; } li.sci { border-left-color: #16a34a; } li.eng { border-left-color: #d97706; }
  li b { font-size: 16px; }
  li small { color: #6b7280; font-size: 13px; display: block; }
  .due { font-size: 13px; font-weight: 700; padding: 4px 10px; border-radius: 999px; background: #e5e7eb; white-space: nowrap; }
  .due.soon { background: #ffe3b8; color: #7a4300; }
  .due.late { background: #fbd0d0; color: #8a1c1c; }
  .empty { padding: 14px; color: #6b7280; }
  .foot { margin-top: 12px; font-size: 14px; color: #4b5563; }
</style>
</head>
<body>
<div class="wrap">
  <h1>Period 3 &middot; Homework board</h1>
  <p class="sub">Mr. Okafor &middot; Room 204 &middot; Help hour Wednesdays 3:15</p>
  <div class="chips" id="chips"></div>
  <ul id="list"></ul>
  <p class="foot">Missing a handout? It is on the table by the door. Questions: t.okafor@riverton.example</p>
</div>

<script>
  // Due dates are written as "days from today" so this demo never goes stale.
  // On your own page, use real dates instead.
  const items = [
    { subject: 'Math',    cls: 'math', title: 'Problems 1-12, page 84', note: 'Show your steps', days: 1 },
    { subject: 'Science', cls: 'sci',  title: 'Lab report: conclusion', note: 'Three sentences',  days: 2 },
    { subject: 'English', cls: 'eng',  title: 'Read chapters 5 and 6',  note: 'Bring one question', days: 3 },
    { subject: 'Math',    cls: 'math', title: 'Unit quiz review sheet',  note: 'Use the answer key', days: 6 },
    { subject: 'English', cls: 'eng',  title: 'Essay outline',           note: 'One page, bullets ok', days: 8 },
    { subject: 'Science', cls: 'sci',  title: 'Bring a leaf sample',     note: 'Any tree on the street', days: 9 }
  ];
  const subjects = ['All', 'Math', 'Science', 'English'];
  const chips = document.getElementById('chips');
  const list = document.getElementById('list');
  let current = 'All';

  function label(days) {
    if (days < 0) return ['Late', 'late'];
    if (days === 0) return ['Due today', 'soon'];
    if (days === 1) return ['Due tomorrow', 'soon'];
    return ['Due in ' + days + ' days', ''];
  }

  function render() {
    chips.innerHTML = '';
    subjects.forEach((s) => {
      const b = document.createElement('button');
      b.type = 'button';
      b.textContent = s;
      b.setAttribute('aria-pressed', s === current);
      b.addEventListener('click', () => { current = s; render(); });
      chips.appendChild(b);
    });
    list.innerHTML = '';
    const shown = items.filter((it) => current === 'All' || it.subject === current);
    if (!shown.length) { list.innerHTML = '<li class="empty">Nothing due.</li>'; return; }
    shown.forEach((it) => {
      const [text, kind] = label(it.days);
      const li = document.createElement('li');
      li.className = it.cls;
      li.innerHTML = '<div><b>' + it.title + '</b><small>' + it.subject + ' &middot; ' + it.note + '</small></div>' +
        '<span class="due ' + kind + '">' + text + '</span>';
      list.appendChild(li);
    });
  }
  render();
</script>
</body>
</html>
Tap a subject to filter. Due labels turn orange when the date is near.

In this demo the due dates are written as days from today so it never goes stale. On your own page, ask the AI to use real dates. Then change them in the document each week, and the link stays the same.

One pasted page or a site builder

A builder gives you many pages, menus and themes. A pasted page gives you one page that you control completely. Google Sites is one builder that many schools already use.

AI page + NOS link Google Sites
What you make One page of HTML A site with pages and menus
Who can open it Anyone with the link, no account You choose Restricted or Public when you publish
Where you edit Your NOS document The Sites editor
After you edit the page The same link shows the new version See Google's help

Google's Publish your site page says you can publish and decide who can see it, and that work or school accounts may have other options. If your school wants the page inside a Sites page, see adding HTML to Google Sites.

When it does not work

Symptom Cause Fix
A link on the page opens an error page The AI invented the address Click every link before you share, and paste in the real one
The page looks tiny on a phone The AI left out the phone settings Ask for a one-column page that works on a phone
Pictures are missing The AI used an outside image Ask for shapes or colours only, no images
Tapping the email does nothing The email is only a button Show the address as text too, so it can be typed or copied
Families still ask where the page is The link is only in one place Post it in Stream and Classwork, and print it on the handout
The page shows last week The old text is still in the document Edit the document. The same link shows the change
A student cannot open it at school Managed devices can block addresses Ask your school IT to allow it

School administrators can block or allow websites on managed Chromebooks, according to Google's Allow or block access to websites page. For phone problems, opening an HTML file on a phone covers the usual causes.

Questions people ask

Do I need a website builder for a classroom website?

Not for a one-page class site. An AI chat can write the whole page as a single HTML file, and a NOS share link publishes it. A builder is still a fine choice if you want many pages or your school already supplies one.

Is it really free?

NOS has a Free plan, and as of October 2026 its pricing page lists 3 live share links on it, which is enough for one class site with room to spare. Published pages on Free carry a NOS badge. Plans can change, so check the pricing page, and check the plan of whichever AI chat you use.

Do families need an account to open it?

No. Anyone with the link can open the page in a browser, on a phone too, without signing in. They can read it, but they cannot edit it.

How do I update the schedule each week?

Change the text in your NOS document, or ask the AI for a new version and paste it over the old one. The share link stays the same, so nothing needs to be re-posted.

Can I put student names or photos on it?

Keep them off. Anyone who has the link can open the page, and a shared page has no password. Follow your school's privacy rules, and put only what you would be happy to see on a notice board outside the school.

Keep reading