Source Code

<div class="container py-5 d-flex justify-content-center">
  <div class="card bsenv-card">
    <div class="card-body p-3">
      <div class="d-flex justify-content-between align-items-center mb-2">
        <h6 class="fw-bold mb-0">Environment variables</h6>
        <span class="badge text-bg-secondary">production</span>
      </div>
      <ul class="list-unstyled mb-0" id="bsenvList"></ul>
    </div>
  </div>
</div>

Bootstrap Environment Variable Viewer — Free HTML CSS JS Snippet

Bootstrap Environment Variable Viewer · Dashboards · Plain HTML, CSS & JS · Live preview

What's included

Features

Only variables actually marked secret get a Reveal/Hide toggle at all — plain values show directly
Each secret's revealed state is tracked independently in a Set, never a single shared show-all flag
The masked placeholder scales with the real value's length, hinting at scale without leaking content
Copy always copies the true underlying value, regardless of whether it's currently masked on screen
A brief "Copied" confirmation on the Copy button itself, reverting automatically

About this UI Snippet

Bootstrap Environment Variable Viewer — HTML, CSS & JavaScript

Screenshot of the Bootstrap Environment Variable Viewer snippet rendered live

Each variable carries its own secret boolean, and that's what decides two things independently: whether a Reveal/Hide toggle exists for it at all, and whether its value starts masked. A non-secret variable like NODE_ENV never gets a Reveal button in the first place — there's nothing sensitive to hide, so offering a toggle that does nothing meaningful would just be clutter.

Which secrets are currently revealed lives in one revealed Set holding row indices, checked per row with revealed.has(i) — toggling one variable's visibility only ever adds or removes its own index, leaving every other secret's masked/revealed state completely untouched, unlike a single shared "show secrets" boolean that would reveal or hide everything at once.

mask() renders a bullet character repeated up to the real value's length (capped at 24) rather than a fixed-width placeholder — a short value and a long one look visibly different even while both are hidden, giving a rough sense of scale without leaking the actual content. Copy always copies the real, unmasked value regardless of whether it's currently visible on screen, since the whole point of a Copy button next to a secret is to get the real value into a paste target without necessarily displaying it on screen first.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Hand this snippet to an AI coding assistant like Claude and ask it to add a "Reveal all" / "Hide all" toggle above the list that affects every secret at once while still supporting individual per-row toggling afterward, or to add a short auto-re-mask timer that hides a revealed secret again after a set number of seconds of inactivity.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a Bootstrap 5.3 environment variable viewer, using the real Bootstrap CDN framework (bootstrap.min.css and bootstrap.bundle.min.js), not custom CSS made to resemble it.

Requirements:
- A list of at least 5 sample environment variables, each with a key and a value, where some are marked as secret and some are not.
- Non-secret variables display their real value plainly with no reveal control. Secret variables display a masked placeholder by default (visually scaled to roughly match the real value's length) with a per-row "Reveal"/"Hide" toggle button.
- Track which secrets are currently revealed independently per row (e.g. in a Set of indices), so revealing one secret has no effect on any other secret's visibility state.
- Every variable, secret or not, has a "Copy" button that copies its real underlying value to the clipboard regardless of whether it's currently masked or revealed on screen, with a brief "Copied" confirmation that reverts automatically.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the snippetNODE_ENV and PUBLIC_API_URL show their real values plainly; every other variable shows masked bullets with a Reveal button.
  2. 2
    Click "Reveal" next to DATABASE_URLIts real connection string appears, and the button relabels itself "Hide".
  3. 3
    Click "Reveal" on a second secret, like STRIPE_SECRET_KEYIt reveals independently — DATABASE_URL stays revealed and unaffected.
  4. 4
    Click "Hide" on DATABASE_URLOnly that one value re-masks; STRIPE_SECRET_KEY stays revealed.
  5. 5
    Click "Copy" on a still-masked secretThe real value is copied to your clipboard even though it's never been revealed on screen.

Real-world uses

Common Use Cases

DEV
Internal admin tools and deployment dashboards
Pairs with bootstrap-deployment-status-panel for a fuller internal ops/config review panel.
API key and credential management screens
The reveal-on-demand pattern is the standard way sensitive config values are shown in most cloud provider dashboards.
CI/CD pipeline configuration review
Let an operator double-check which secrets are set for an environment without exposing them all by default.

Got questions?

Frequently Asked Questions

Only variables marked secret: true render one — a plainly public value like NODE_ENV or an API base URL has nothing to hide, so there's no reveal/hide state relevant to it at all.

No — each secret's visibility is tracked independently by its own index in a Set, so revealing one has zero effect on any other secret's masked or revealed state.

Yes — the Copy button always reads the real value directly from the underlying VARS array, regardless of whether that row is currently showing the masked placeholder or the real text.

Yes. Keep the revealed row indices in a Set (or an equivalent structure) in component state, and derive each row's displayed value and button label from whether its index is present in that state.