There are three ways to put JavaScript on a page. They work like the three ways to add CSS.
1. Inline
JavaScript written in an HTML attribute.
<button onclick="console.log('Clicked')">Click me</button>
It works, but it mixes behaviour into the HTML and gets messy fast. You will see it in older code and quick demos. Prefer the other two.
2. Internal
JavaScript inside a <script> element.
<p id="out"></p>
<script>
document.querySelector("#out").textContent = "Written inside the page";
</script>
Good for small demos, and every example in this course uses it so you can see the HTML and the script together.
3. External
JavaScript in its own file, linked with src.
<script src="app.js" defer></script>
console.log("Loaded from a file");
One file can be shared by every page, and the browser can cache it. This is the right choice for real websites.
Where does the script tag go?
A script can only see elements that already exist. If it runs before the HTML below it is read, document.querySelector() finds nothing. There are two good solutions:
- Put the
<script>at the end of the<body>, or - Put it in the
<head>with thedeferattribute. The file downloads while the page loads, and runs after the HTML is parsed.
| Attribute | Behaviour |
|---|---|
| (none) | Stops HTML parsing while it downloads and runs |
defer | Downloads in parallel, runs after the page is parsed, keeps order |
async | Downloads in parallel, runs as soon as it is ready, in any order |
type="module" | A module. Deferred by default. See Browser Modules |
For most pages: defer, or type="module".
Null errors from a script in the head
Cannot read properties of null, your script probably ran before the element existed. Add defer or move the script down.