How to send an HTML file in Google Classroom

Do not attach the .html file. Put the page at a link and add that link to the assignment, so students tap it and the page opens in the browser.

To send an HTML page in Google Classroom, put the page at a web link and add that link to the assignment. Attaching the .html file itself gives students a file, and what they do with it depends on their device.

A question in Google's Classroom community asks the same thing: how to get an HTML file attached to an assignment to open in Chrome, not Docs.

Here is a page you could post. It is a four-question quiz for a class. Answer it, press the button, then read on to see how it gets from a chat window into Classroom.

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>Water cycle check</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; padding: 18px 14px 28px; font-family: system-ui, sans-serif; background: #f4f6fa; color: #1d2330; }
  main { max-width: 560px; margin: 0 auto; }
  h1 { font-size: 22px; margin: 0 0 4px; }
  .sub { margin: 0 0 16px; color: #566; font-size: 15px; }
  fieldset { border: 1px solid #d9dee8; border-radius: 12px; background: #fff; margin: 0 0 12px; padding: 12px 14px; }
  legend { font-weight: 700; padding: 0 6px; font-size: 15px; }
  label { display: block; padding: 8px 6px; border-radius: 8px; cursor: pointer; font-size: 16px; }
  label:hover { background: #eef2fb; }
  label.right { background: #dcf3e4; }
  label.wrong { background: #fde3d6; }
  button { font: inherit; font-weight: 700; padding: 11px 20px; border: 0; border-radius: 10px; background: #1d4ed8; color: #fff; cursor: pointer; }
  button.alt { background: #e5e9f2; color: #1d2330; margin-left: 8px; }
  #result { margin-top: 14px; font-size: 18px; font-weight: 700; min-height: 26px; }
</style>
</head>
<body>
<main>
  <h1>Water cycle: quick check</h1>
  <p class="sub">Pick one answer for each question, then press Check.</p>
  <form id="quiz"></form>
  <button type="button" id="check">Check my answers</button>
  <button type="button" id="reset" class="alt">Start again</button>
  <p id="result" aria-live="polite"></p>
</main>

<script>
  // Each question: text, choices, and the index of the right choice
  const questions = [
    { q: 'What turns liquid water into vapour?', a: ['Evaporation', 'Condensation', 'Precipitation'], right: 0 },
    { q: 'Clouds form when vapour cools and...', a: ['melts', 'condenses', 'freezes solid'], right: 1 },
    { q: 'Rain, snow and hail are all kinds of...', a: ['runoff', 'evaporation', 'precipitation'], right: 2 },
    { q: 'Which source of energy drives the water cycle?', a: ['The Sun', 'The Moon', 'Wind turbines'], right: 0 }
  ];
  const form = document.getElementById('quiz');
  const result = document.getElementById('result');

  function build() {
    form.innerHTML = '';
    questions.forEach((item, i) => {
      const box = document.createElement('fieldset');
      const legend = document.createElement('legend');
      legend.textContent = (i + 1) + '. ' + item.q;
      box.appendChild(legend);
      item.a.forEach((text, j) => {
        const label = document.createElement('label');
        const input = document.createElement('input');
        input.type = 'radio';
        input.name = 'q' + i;
        input.value = j;
        label.appendChild(input);
        label.appendChild(document.createTextNode(' ' + text));
        box.appendChild(label);
      });
      form.appendChild(box);
    });
    result.textContent = '';
  }

  document.getElementById('check').addEventListener('click', () => {
    let score = 0;
    questions.forEach((item, i) => {
      const labels = form.querySelectorAll('input[name="q' + i + '"]');
      labels.forEach((input, j) => {
        const label = input.parentElement;
        label.classList.remove('right', 'wrong');
        if (j === item.right) label.classList.add('right');
        else if (input.checked) label.classList.add('wrong');
      });
      const picked = form.querySelector('input[name="q' + i + '"]:checked');
      if (picked && Number(picked.value) === item.right) score++;
    });
    result.textContent = 'You got ' + score + ' out of ' + questions.length + '.';
  });

  document.getElementById('reset').addEventListener('click', build);
  build();
</script>
</body>
</html>
A self-marking quiz in one HTML file. Pick answers and press Check.

The answers are inside the file, so treat a page like this as practice, not as a graded test. Building an HTML quiz explains why.

Make it with AI

You do not need to write any code. Describe the page in plain words and ask for one file.

Make a single-file HTML page for a class of 10-year-olds.
Topic: the water cycle. Four multiple-choice questions with three
choices each. A button "Check my answers" shows the score and marks
right answers green and wrong ones orange. Large text that works on
a phone and a Chromebook. No external images, fonts or scripts.
Return only the HTML.

Check three things in the result before you copy it:

  • The answers are correct. AI can state a wrong answer with confidence.
  • The page works with no internet-only parts. Ask again if you see a link to an outside script or image.
  • The text is large enough to read on a small screen.

Here is a second kind of page. A lesson page with a shaded bar, show-the-answer boxes and a tick list.

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>Lesson page: Fractions</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; padding: 0 0 28px; font-family: system-ui, sans-serif; background: #fff; color: #1d2330; line-height: 1.5; }
  header { background: #0f766e; color: #fff; padding: 20px 16px; }
  header h1 { margin: 0; font-size: 22px; }
  header p { margin: 4px 0 0; opacity: .9; font-size: 15px; }
  main { max-width: 560px; margin: 0 auto; padding: 16px; }
  h2 { font-size: 17px; margin: 22px 0 8px; }
  .bar { display: flex; height: 44px; border-radius: 8px; overflow: hidden; border: 2px solid #0f766e; max-width: 360px; }
  .bar span { flex: 1; border-right: 2px solid #0f766e; background: #fff; }
  .bar span:last-child { border-right: 0; }
  .bar span.on { background: #99e0d6; }
  .row { display: flex; gap: 8px; margin: 10px 0 4px; flex-wrap: wrap; }
  button { font: inherit; padding: 9px 14px; border: 1px solid #0f766e; border-radius: 8px; background: #fff; color: #0f766e; cursor: pointer; font-weight: 600; }
  button[aria-pressed="true"] { background: #0f766e; color: #fff; }
  ul.tasks { list-style: none; margin: 0; padding: 0; }
  ul.tasks li { padding: 6px 0; }
  ul.tasks label { cursor: pointer; font-size: 16px; }
  details { border: 1px solid #d9dee8; border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; }
  summary { cursor: pointer; font-weight: 600; }
  #done { font-weight: 700; color: #0f766e; margin-top: 8px; min-height: 24px; }
</style>
</head>
<body>
<header>
  <h1>Lesson: Fractions of a bar</h1>
  <p>Grade 4 maths, 20 minutes. Work through the three parts.</p>
</header>
<main>
  <h2>1. Shade the bar</h2>
  <p>Choose how many of the 8 parts to shade.</p>
  <div class="bar" id="bar"></div>
  <div class="row" id="picks"></div>
  <p id="say"></p>

  <h2>2. Try these</h2>
  <details><summary>Shade 4 parts. What fraction is that?</summary><p>4/8, which is the same as 1/2.</p></details>
  <details><summary>Shade 2 parts. What fraction is that?</summary><p>2/8, which is the same as 1/4.</p></details>

  <h2>3. Tick when finished</h2>
  <ul class="tasks">
    <li><label><input type="checkbox"> I shaded the bar</label></li>
    <li><label><input type="checkbox"> I tried both questions</label></li>
    <li><label><input type="checkbox"> I can say 4/8 is one half</label></li>
  </ul>
  <p id="done"></p>
</main>

<script>
  const bar = document.getElementById('bar');
  const picks = document.getElementById('picks');
  const say = document.getElementById('say');
  const parts = [];

  for (let i = 0; i < 8; i++) {
    const s = document.createElement('span');
    bar.appendChild(s);
    parts.push(s);
  }

  function shade(n) {
    parts.forEach((s, i) => s.classList.toggle('on', i < n));
    say.textContent = n + '/8 of the bar is shaded.';
    picks.querySelectorAll('button').forEach((b) => b.setAttribute('aria-pressed', String(Number(b.dataset.n) === n)));
  }

  [1, 2, 4, 6, 8].forEach((n) => {
    const b = document.createElement('button');
    b.textContent = n;
    b.dataset.n = n;
    b.setAttribute('aria-pressed', 'false');
    b.addEventListener('click', () => shade(n));
    picks.appendChild(b);
  });

  const boxes = document.querySelectorAll('.tasks input');
  boxes.forEach((box) => box.addEventListener('change', () => {
    const all = [...boxes].every((b) => b.checked);
    document.getElementById('done').textContent = all ? 'All done. Well done!' : '';
  }));
  shade(3);
</script>
</body>
</html>
A lesson page with an interactive bar, answers that open on click and a tick list.

Open a NOS document and paste the HTML in. The page renders right there and its scripts run. Test every button yourself. Then choose Create share link and copy the address.

Anyone with that address can open the page in a browser, on a phone too, without an account. They can use it, but they cannot edit it.

If you spot a mistake tomorrow, change the code in your NOS document. The same link then shows the new version. HTML to link walks through the whole thing.

From an AI chat to a link in the assignment: four steps.
From an AI chat to a link in the assignment: four steps.

Google's help page for creating an assignment lists the attach options. One of them is Link, described as attaching a link to your assignment. The page is at Create an assignment.

  1. Open the class, go to Classwork, and choose Create, then Assignment.
  2. Enter a title and instructions.
  3. Under the attach options, choose Link.
  4. Paste the NOS address and add it.
  5. Assign or schedule the post.

A material post on the Classwork page accepts links as well, according to Add materials to the Classwork page. Use that for a reference page that is not an assignment.

The student taps the link in the assignment and the page opens.
The student taps the link in the assignment and the page opens.

Classroom has three attach routes that could carry an HTML page. They behave differently.

Upload the .html file Attach from Drive Add a Link
What the student gets A file A Drive file A web address
Opens as a page Not promised See below Yes, it is a web page
Fix a mistake later Upload the file again Change the Drive file Edit once, same link
Needs an account Classroom login Classroom login None for the NOS page

For a Drive file, Google offers three student options: view, edit, or a copy for each student.

A page that runs needs a place that serves it as a page, and Drive stores files rather than serving pages.

An attached file arrives as a file. A link arrives as a page.
An attached file arrives as a file. A link arrives as a page.

Check it the way students will see it

Before you post, open the link on the device your class uses. On a school Chromebook, sign in as a student if your school gives you a test student account. Then try a phone.

Google's list of file types that work on Chromebooks does not include .html, as of October 2026. That is one more reason to send an address, not a file. If a class works on phones, read opening an HTML file on a phone.

If your students work in Google Sites, embedding HTML in Google Sites is another route.

Students can also send a link back. In Classroom's turn-in options they choose Add or create, then Link, and paste an address.

When it does not work

Symptom Cause Fix
Students say the page will not open at school The school may block some sites on managed devices Ask your school IT to allow the address
The quiz shows no score The page has an error, or the AI left out the script Test it in NOS and ask the AI to fix it
Pictures are missing The AI used an outside image Ask for inline SVG or CSS shapes only
The link opens but looks tiny on a phone The page lacks a viewport setting Ask the AI to make it mobile friendly
You want to see who finished A shared page does not report that Ask for a screenshot or answer in Classroom
A student's ticks vanish on reload A visitor's changes are not saved Tell them it is practice only

School administrators can block or allow addresses on managed Chromebooks, according to Google's Allow or block access to websites page. Whether that applies to your students depends on your school's settings.

Questions people ask

Can I attach an .html file to a Google Classroom assignment?

Classroom lets you attach a file from Drive or upload one from your computer, and its help pages do not list file types. What students see for an .html file depends on their device and apps. A link avoids that question, because a link opens a web page.

Where do I paste the link in Classroom?

Create an assignment, choose Link under the attach options, enter the web address and add it. Material posts on the Classwork page accept links in the same way.

Will I see which students opened the page or what they scored?

No. A NOS page does not report who opened it, and a score shown in the page stays on the student's screen. Use the page for practice, or ask students to turn in a screenshot or a short answer in Classroom.

Do students need an account to open the link?

Not for the NOS page. The link opens without signing in. Students still use their normal Classroom login to reach the assignment itself.

I fixed a typo. Do I need to post a new link?

No. Edit the page in NOS and the same link shows the new version. The assignment does not need to change.

Keep reading