<script
<script>
Level 8 — Metadata, SEO & Head Used to embed or reference executable code, almost exclusively JavaScript.
1. Prerequisites
<body>—- Element vs. Tag — The
<script>tag is NOT a void element; it must have a closing tag, even if it is empty!
2. Term Category
Metadata / Interactive Tag (Universal Browser Support): <script> is a fundamental concept in this technology stack. Level 8 — Metadata, SEO & Head
3. Explanation
(1) Design Motivation — "Why did we design this?"
HTML provides the structure. CSS provides the design. But what if you want logic? What if you want a modal popup to appear when a button is clicked, or you want to fetch new data from a server without refreshing the page?
The W3C created the <script> tag to inject programming logic into the static HTML document. When the browser is reading the HTML file and encounters a <script> tag, it literally pauses rendering the webpage, executes the JavaScript code, and then resumes rendering.
You can either write the JavaScript directly inside the tags, or use the src attribute to link to an external .js file (which is the preferred, cleaner method).
(2) Reality Metaphor
If building a website is like building a robot:
HTML is the metal chassis (the structure).
CSS is the paint job (the design).
The <script> tag is the computer chip you plug into the robot's head that actually makes it move and think.
(3) Code Examples
Short Snippet
<!-- Method 1: Linking to an external JavaScript file (Preferred) -->
<script src="app.js"></script>
<!-- Method 2: Writing JavaScript directly inline -->
<script>
console.log("Hello from JavaScript!");
</script>
Fuller Example
<body>
<h1>Welcome to my App</h1>
<button id="alertBtn">Click Me</button>
<!-- Scripts are often placed at the very bottom of the body -->
<!-- This ensures the HTML above it has finished loading before the script runs -->
<script>
const button = document.getElementById('alertBtn');
button.addEventListener('click', () => {
alert('You clicked the button!');
});
</script>
</body>
4. Common Mistakes & Pitfalls
Mistake 1: Treating <script> as a void element
The mistake: Using a self-closing syntax when linking to an external file, like <script src="app.js" />.
Why it's wrong: In HTML5, <script> is not a void element. It absolutely requires a closing </script> tag. If you omit the closing tag, the browser will think the rest of your entire HTML document is part of the script, and the webpage will go completely blank! Even if you use the src attribute and the space between the tags is completely empty, you must close it.
Incorrect:
<!-- Will break the webpage -->
<script src="main.js" />
Fix:
<!-- Always include the closing tag! -->
<script src="main.js"></script>
Mistake 2: Putting the script in the <head> without defer
The mistake: Putting <script src="app.js"></script> in the <head> of the document without any special attributes.
Why it's wrong: The browser reads HTML top-to-bottom. If it hits a giant script in the <head>, it will pause drawing the webpage until the script downloads and runs. This makes the website load very slowly (a "render-blocking" script). Furthermore, if the script tries to attach an event to a <button> that is down in the <body>, it will fail because the browser hasn't drawn the button yet!
Solution: Either put the <script> at the very bottom of the <body>, OR add the defer attribute (<script src="app.js" defer></script>) which tells the browser to download the script in the background and wait to run it until the HTML is fully drawn.
Mistake 3: Placing Blocking <script> Tags in <head> Without defer or async
The mistake: Placing <script src="app.js"></script> in <head> without defer or async.
Why it's wrong: Un-deferred scripts in <head> block HTML parsing until downloaded and executed, creating a blank white screen during page loads. Add defer or move to bottom of <body>.
Incorrect:
<head>
<script src="heavy.js"></script> <!-- ❌ Blocks HTML parsing! Blank page! -->
</head>
Fix:
<head>
<script src="heavy.js" defer></script> <!-- Non-blocking deferred loading -->
</head>
Mistake 4: Combining src Attribute with Inner Inline JavaScript Content in Single Tag
The mistake: Writing <script src="app.js">console.log('hi');</script>.
Why it's wrong: If a <script> tag specifies a src attribute, any inner JavaScript code written between opening and closing tags is IGNORED completely.
Incorrect:
<script src="app.js">
console.log('Test'); // ❌ Inner code is completely ignored!
</script>
Fix:
<script src="app.js"></script>
<script>
console.log('Test'); // Separate inline script tag
</script>
5. Practice Exercises
Exercise 1: Modern ES Module Script Import
Scenario: An author imports a modern JavaScript module using <script type="module" src="...">.
Requirements:
- Add
<script type="module" src="...">in<head>. - Verify automatic deferred execution and strict mode.
Answer
Implementation
<head>
<meta charset="utf-8">
<title>ES Module Web App</title>
<!-- ES6 Module Script (Auto-deferred, strict mode enabled) -->
<script type="module" src="js/main.js"></script>
</head>
Technical Explanation
- The
<script>Element: Embeds or references executable JavaScript code. type="module"Semantics: Imports code as an ES module; automatically executed withdeferbehavior and in strict mode ("use strict").- Module Scope Isolation: Variables defined in modules do NOT pollute the global
windownamespace.
Exercise 2: Inline Application State Bootstrapping Data Script
Scenario: Embeds raw JSON data for client-side state initialization using <script type="application/json">.
Requirements:
- Embed JSON inside
<script type="application/json" id="init-data">.
Answer
Implementation
<!-- Non-executable JSON data payload embedded safely in HTML -->
<script type="application/json" id="user-session-data">
{
"userId": 101,
"username": "JaneDoe",
"roles": ["editor", "admin"]
}
</script>
Technical Explanation
- Non-Executable Data Scripts: Setting
type="application/json"prevents browser from executing content as JS. - Safe State Bootstrapping: Prevents inline XSS vulnerabilities when passing backend data to client scripts.
- DOM Parsing Access: Client JS reads data via
JSON.parse(document.getElementById('user-session-data').textContent).
Exercise 3: Cross-Origin Script Integrity Verification
Scenario: Includes external CDN script with Subresource Integrity (SRI).
Requirements:
- Add
integrityhash andcrossorigin="anonymous".
Answer
Implementation
<script src="https://cdn.example.com/library.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
Technical Explanation
- Subresource Integrity (SRI): Verifies fetched CDN script hash matches
integrityattribute value. - Tampering Prevention: Blocks script execution if CDN file is modified or compromised.
- Mandatory
crossorigin: Requirescrossorigin="anonymous"for cross-domain SRI validation.
6. Related Terms
<link>— Used to import CSS, whereas<script>is used to import JavaScript.defer&async(Script Loading Strategies) — Tag parameters optimized for asynchronous asset parsing.<noscript>— A fallback frame shown if script execution is blocked or disabled.data-*Attributes — Related concept:data-*Attributes.- Render-Blocking Resources — Related concept: Render-Blocking Resources.
- Geolocation API — Related concept: Geolocation API.
- Web Storage (Local/Session Storage) — Related concept: Web Storage (Local/Session Storage).
7. Key Takeaways
- The
<script>tag is used to execute JavaScript logic on a webpage. - It is NOT a void element; you must always write
</script>, even when using thesrcattribute. - Because scripts pause HTML rendering, they should usually be placed at the very bottom of the
<body>tag, or in the<head>using thedeferattribute.