Complete HTML Course Module 5: Intermediate: Page Structure and Semantic HTML

HTML and JavaScript: The script and noscript Tags

  • Beginner
  • Lesson 5.2
  • 5 min read
  • 21 of 69 in the course

In short

The HTML script tag adds JavaScript to your page, either inline or from an external file, and noscript shows a fallback when JavaScript is off. Learn where to put scripts and how defer works. What is the script tag?

The HTML script tag adds JavaScript to your page, either inline or from an external file, and noscript shows a fallback when JavaScript is off. Learn where to put scripts and how defer works.

What is the script tag?

HTML builds the page, CSS makes it look good, and JavaScript makes it do things: react to clicks, check forms, show and hide menus, load new content. Think of a house: HTML is the walls, CSS is the paint, and JavaScript is the electricity.

The <script> element is how you add JavaScript to an HTML page. You can use it in two ways:

  • Inline script: the JavaScript code is written between <script> and </script>.
  • External script: the code lives in a separate .js file, loaded with the src attribute.

You met <script defer> briefly in the lesson about the head section. Here you will learn the whole picture.

Inline JavaScript with the script tag

An inline script is quick to try. Put it at the end of the <body>, so the HTML above it already exists when the script runs.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Today's Date - Green Leaf Cafe</title>
</head>
<body>
  <h1>Green Leaf Cafe</h1>
  <p id="today">Loading the date...</p>

  <script>
    const today = new Date();
    document.getElementById('today').textContent = `Today is ${today.toDateString()}. Come in for a coffee!`;
  </script>
</body>
</html>

When the page opens, the text "Loading the date..." is replaced with something like "Today is Thu Oct 01 2026. Come in for a coffee!". The script finds the paragraph by its id and changes its text with textContent.

Loading an external JavaScript file

For real websites, put JavaScript in its own file, just like CSS. The same file can be shared by every page, and browsers can cache it (save a copy) so later pages load faster.

<script src="js/main.js"></script>
  • src is the path to the file, like an image path.
  • An external script tag must be empty. Any code you write between the tags is ignored when there is a src.
  • The .js file contains only JavaScript, with no <script> tags inside.

A button that changes text

Here is a complete example with two files. First index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Daily Tip - Green Leaf</title>
  <script src="js/tip.js" defer></script>
</head>
<body>
  <h1>Plant tip of the day</h1>
  <p id="tip">Click the button to get a tip.</p>
  <button type="button" id="tip-button">Show me a tip</button>
</body>
</html>

Then js/tip.js:

const tips = [
  'Water when the top 2 cm of soil is dry.',
  'Turn your plant every week so it grows evenly.',
  'Wipe dusty leaves with a damp cloth.'
];

const tipText = document.getElementById('tip');
const button = document.getElementById('tip-button');

button.addEventListener('click', () => {
  const randomIndex = Math.floor(Math.random() * tips.length);
  tipText.textContent = tips[randomIndex];
});

Each click picks a random tip from the list and shows it in the paragraph. addEventListener('click', ...) means "when this button is clicked, run this function". Because the script has defer, it runs after the whole HTML is read, so the button already exists when the code looks for it.

Common mistake: Putting a script in the <head> without defer, then using getElementById. The script runs before the body exists, so it finds null and you get an error like "Cannot read properties of null". Add defer, or move the script to the end of the body.

Where to put the script tag: head with defer or end of body?

There are two good places. Both make sure the HTML is ready before your code runs.

PlacementHow it worksNotes
<head> with deferDownloads while the page loads, runs after the HTML is readModern choice; starts downloading early
End of <body>Runs when the browser reaches it, after the content aboveClassic choice; works everywhere
<head> without deferStops the page until the script downloads and runsAvoid; slows the page

Several deferred scripts always run in the order they appear, so a library can come before the code that uses it. There is also async for independent scripts like analytics, and type="module" for modern JavaScript; these are covered in the lesson about script loading.

Tip: Never put secrets like passwords or API keys in JavaScript on your page. Anyone can read your scripts with View Source or DevTools.

The noscript tag: a fallback when JavaScript is off

Some visitors have JavaScript turned off, some company networks block it, and sometimes a script simply fails to load. The <noscript> element holds content that is shown only when JavaScript is not running. You met it in the lesson about lesser-known elements; here are more ways to use it.

noscript in the body

<h2>Our shop on the map</h2>
<div id="map">Loading the map...</div>
<noscript>
  <p>The interactive map needs JavaScript. Our address is 8 Station Road, Bristol BS1 4DJ. <a href="https://www.openstreetmap.org/">Open a map in a new window</a>.</p>
</noscript>
<script src="js/map.js" defer></script>

With JavaScript on, visitors see the map and never see the message. With it off, they still get the address and a useful link.

noscript in the head

Inside <head>, <noscript> may only contain <link>, <style> and <meta> elements. A common use is to show content that JavaScript would normally reveal with an animation:

<head>
  <meta charset="utf-8">
  <title>Gallery - Green Leaf</title>
  <style>
    .fade-in { opacity: 0; }
  </style>
  <noscript>
    <style>
      .fade-in { opacity: 1; }
    </style>
  </noscript>
</head>

Normally the script fades in elements with the fade-in class. Without JavaScript, the extra style makes them visible at once, so nothing stays invisible forever.

Note: The best websites work at a basic level without JavaScript: links still go somewhere and forms can still submit. JavaScript then makes things nicer. This idea is called progressive enhancement. See MDN: The script element.

Practice exercise

Build a "Like" button for a blog post. Create post.html with a heading, a paragraph and a button that says "Like (0)". Create js/like.js, load it in the head with defer, and make each click increase the number. Add a <noscript> message that says liking needs JavaScript.

Hint: keep a counter with let likes = 0;, add 1 inside the click function with likes++, and then update the button's textContent with a template literal that puts ${likes} inside the brackets.

Key takeaways

  • The <script> element adds JavaScript, either inline or from a file with src.
  • External scripts keep your HTML clean and can be shared and cached.
  • Put scripts in the <head> with defer, or at the end of the <body>.
  • Deferred scripts run in order after the HTML is read.
  • <noscript> shows fallback content when JavaScript is off; in the head it can hold <style>, <link> and <meta>.