Setup & Dependencies

Bootstrap 4 is not a drop-in-one-file library the way you might expect. Its CSS works alone, but every interactive piece — modals, dropdowns, collapses, the components a TrailMap "submit a trail" form would rely on — is a jQuery plugin under the hood, and several of those plugins (dropdowns, tooltips, popovers) also depend on Popper.js for positioning. Getting the script order wrong is the single most common reason a Bootstrap 4 page "looks right but nothing clicks."

Including Bootstrap 4 via CDN

The CSS is a single stylesheet link in <head>:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.6.2/css/bootstrap.min.css">

The Required Script Order: jQuery, Then Popper.js, Then Bootstrap

Bootstrap 4's JavaScript bundle assumes jQuery is already on the page and assumes Popper.js is already on the page. Load them in the wrong order — or skip Popper — and dropdowns, tooltips, and popovers silently fail to position themselves, even though the console may stay quiet. The three scripts go at the bottom of <body>, in this exact order:

<!-- 1. jQuery first -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>

<!-- 2. Popper.js second -->
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>

<!-- 3. Bootstrap's JS last -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.6.2/js/bootstrap.min.js"></script>
Note: This is different from Bootstrap 5, which dropped the jQuery dependency entirely and no longer needs a separate jQuery script. In Bootstrap 4, skip jQuery or Popper and the JS-driven components simply don't work.

The Viewport Meta Tag

Bootstrap 4's grid and responsive utilities are built mobile-first, and that only works correctly if the browser is told not to scale the page down on phones. This tag belongs in every page's <head>, before any Bootstrap CSS:

<meta name="viewport" content="width=device-width, initial-scale=1">

Putting It Together: A TrailMap Page Head

A minimal TrailMap homepage head, with everything in the order that actually works:

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>TrailMap</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.6.2/css/bootstrap.min.css">
</head>
<body>
  <!-- page content -->

  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.6.2/js/bootstrap.min.js"></script>
</body>

Installing via npm for a Sass Build Workflow

If TrailMap needs custom theme colors or trims unused components to cut file size, the CDN approach isn't enough — that requires compiling Bootstrap's Sass source yourself:

# install Bootstrap 4 and its peer dependencies
npm install bootstrap@4.6.2 jquery popper.js

With npm, you import bootstrap.scss into your own Sass entry file so you can override variables like $primary before Bootstrap's own rules are compiled, and a bundler (webpack, Parcel, etc.) is responsible for wiring up jQuery and Popper as modules instead of global <script> tags.

Up next: With Bootstrap 4 loading correctly, the first layout building block is the Containers lesson.