Bootstrap 5 JavaScript Plugin Lifecycle
Use the Button API without double initialization, then remove both plugin and caller-owned behaviour deliberately.
How it works
getOrCreateInstance returns an existing plugin instance or creates one. dispose releases that plugin’s stored behaviour and references; it does not magically remove arbitrary listeners your application registered. Keep those responsibilities separate when replacing interface fragments. This example controls a toggle button through the API instead of also attaching data-bs-toggle, avoiding a double-toggle path. An AbortController gives the application a clear route to remove its own listener when the example is disposed.
Run and inspect
Save the complete document as index.html in a separate lab folder. Place Bootstrap 5.3.8 CSS and the matching JavaScript bundle beside it. Open the file in a normal browser. A separate local static server is optional; no database or PHP execution is required. Keep the Bootstrap licence and bundled Popper licence with redistributed assets.
Download this complete HTML source.
This example needs the complete local setup with the Bootstrap JavaScript bundle. The restricted CSS playground does not reproduce this example’s full contract.
Example
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 5 Own Plugin Instances and Application Listeners Separately</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<main class="container py-4">
<h1 class="h3 mb-4">Repair day</h1>
<button id="api-toggle" class="btn btn-outline-primary" type="button" aria-pressed="false">Local selection</button><button id="dispose-toggle" class="btn btn-link" type="button">Dispose example</button><p id="api-status" class="mt-3 mb-0">Ready.</p>
</main>
<script src="bootstrap.bundle.min.js"></script>
<script>
const control = document.querySelector("#api-toggle");
const listeners = new AbortController();
control.addEventListener("click", () => bootstrap.Button.getOrCreateInstance(control).toggle(), { signal: listeners.signal });
document.querySelector("#dispose-toggle").addEventListener("click", () => {
listeners.abort();
bootstrap.Button.getInstance(control)?.dispose();
document.querySelector("#api-status").textContent = "Disposed.";
});
</script>
</body>
</html>
Expected result
The selection button toggles its pressed state. Disposing removes the plugin instance and the application listener, so later clicks no longer toggle it.
The callback invokes the Button plugin explicitly. The dispose control aborts the listener before disposing the stored instance. Real applications should also handle component-specific lifecycle events and asynchronous transitions before removing markup. Data attributes are convenient initialization, but mixing them blindly with manual handlers can execute an operation twice.
Check Bootstrap’s official 5.3 documentation for component contracts and version details.