A warm, editorial newsletter popup built on the Bootstrap 6 Dialog component. A photo fills one side, and the other side has a headline, an email field with a Subscribe button and a "Don't show this again" checkbox. The popup opens after a short delay, remembers visitors who opt out or subscribe, and ends with a confirmation screen. It fits blogs, magazines and content sites.
How it works
The root .nlp-root shows a sample article with a "Get the newsletter" button (data-bs-toggle="dialog") and a <dialog class="dialog dialog-slide-up nlp-dialog">. Inside, .nlp-layout is one column on phones (a short photo banner on top) and becomes a two-column grid from 768px, with .nlp-media on the left.
script.js reads data-nlp-delay from the root and opens the dialog after that many milliseconds, unless storage says the visitor has opted out. Submitting .nlp-form checks the email field and marks errors with .is-invalid. Because the feedback is a sibling of the .input-group inside .form-field, Bootstrap shows the message. A valid email shows a spinner, then .nlp-pane--done with the address, and stores the opt-out flag. If the checkbox is ticked when hidden.bs.dialog fires, the flag is stored too. Storage is wrapped in try/catch, so the popup still works in sandboxed iframes and private modes.
The photo comes from Unsplash; replace it with your own image.
Customization
--nlp-accenton.nlp-root: the terracotta brand color. It feeds--bs-primary-bg(Subscribe button) and--bs-control-checked-bg(checkbox).data-nlp-delayon.nlp-root: the delay in milliseconds (the demo uses600; 5000 to 15000 is common). Remove the attribute to open the popup only from the button.STORAGE_KEYinscript.js: rename it if you run several popups on one domain.grid-template-columnson.nlp-layout(desktop media query): change the photo-to-text ratio, or hide.nlp-mediafor a text-only popup.--bs-dialog-widthon.nlp-dialog: the popup width (48rem).- Replace the
setTimeoutin the submit handler withfetch('/api/newsletter', …)for your email provider.
Use cases
- Blogs and magazines: the popup opens after a short delay with a photo and a headline
- Content sites: visitors can tick Don't show this again and will not see the popup next time
- Newsletter growth: the email field is validated before showing a confirmation screen
- Editorial sites: a photo banner stacks above the text on phones
Accessibility
The dialog is labelled by its headline and described by the intro text. The email field has a visually hidden label, aria-invalid and a visible error message. The opt-out checkbox has a real <label for>. When the confirmation appears, its heading receives focus. Escape and the close button dismiss the popup, and Bootstrap traps focus while it is open. The slide-up transition is skipped under prefers-reduced-motion.
Bootstrap 6 notes
This is built on Bootstrap 6.0.0-alpha.1, and alpha APIs can still change. The BS5 modal becomes <dialog class="dialog">, and dialog-slide-up is a new entrance variant. form-check is replaced by a bare .check, and the button inside the input group uses btn-solid theme-primary input-group-btn. Dialog.getOrCreateInstance() is imported from the bundle module.