Quick start
Add ViewShield to any page in three steps. Only marked elements are protected — the rest of your site stays normal HTML.
- Load the scripts from
https://idenforcer.com/viewshield/after your protected HTML is in the DOM. - Mark sensitive text with
data-protectedon any display element (span, div, td, p, etc.). - Initialize once when ready:
ViewShield.init({ … }).
<!-- 1. Mark sensitive displayed values -->
<label>License</label>
<span data-protected>DL-8847291</span>
<label>Name</label>
<span>John Doe</span> <!-- not protected -->
<!-- 2. Standard styling (matches live demo) -->
<link rel="stylesheet" href="https://idenforcer.com/viewshield/includes/viewshield-protected.css">
<!-- 3. Load ViewShield (hosted on IDEnforcer) -->
<script src="https://idenforcer.com/viewshield/TemporalTileEngine.js"></script>
<script src="https://idenforcer.com/viewshield/ViewShieldV5.js"></script>
<!-- 4. Initialize — only licenseKey required; other options match the demo -->
<script>
ViewShield.init({
licenseKey: "VS-XXXX-XXXX-XXXX",
protectedSelector: "[data-protected]"
});
</script>
User ID & session ID — optional
userId and sessionId are not provided by IDEnforcer. They come from your own application — the same login/session data you already have when you render the page.
| Option | Where you get it | Required? |
|---|---|---|
licenseKey | Your ViewShield purchase email / IDEnforcer admin | Yes |
userId | Your logged-in user’s ID, username, or employee number ($_SESSION['user_id'], currentUser.id, etc.) | No — defaults to "anonymous" |
sessionId | Your PHP session ID, JWT session token, or a per-page ID (session_id(), "page-" + Date.now()) | No — auto-generated if omitted |
userId and sessionId entirely. ViewShield still works — only the license key is required.PHP — server knows who is logged in
<script>
document.addEventListener("DOMContentLoaded", function () {
ViewShield.init({
licenseKey: "<?= htmlspecialchars($viewshieldLicenseKey) ?>",
protectedSelector: "[data-protected]",
userId: "<?= (int)($_SESSION['user_id'] ?? 0) ?>",
sessionId: "<?= session_id() ?>"
});
});
</script>
React / Vue — from your auth context
ViewShield.init({
licenseKey: "VS-XXXX-XXXX-XXXX",
protectedSelector: "[data-protected]",
userId: String(user.id), // from your auth provider
sessionId: user.sessionToken // or auth.session.id
});
These values are stored in ViewShield config and returned by ViewShield.getStatus() for your own audit trails. The on-screen watermark shows a date/time stamp — not the user ID.
How it works
ViewShield finds every element matching your selector, hides the raw text, and draws a canvas overlay using the element's computed font. Each animation frame, a subset of tiles is visible, inverted, dimmed, or noised — the full value never appears in a single frame, so a photo or screenshot captures an incomplete image.
licenseKey. The engine validates against /api/viewshield/validate.php on init and every 10 minutes. Cancelled, suspended, or expired subscriptions stop rendering immediately.Licensing
Purchase at idenforcer.com/pay.php?plugin=viewshield ($4.99/mo or $53.89/yr). You receive a license key by email.
- Domain binding — first site use auto-registers the domain (up to 5 per license). Add more in Admin → Plugins → Licenses.
- Live validation — payment lapse, suspension, or cancellation disables protection on the customer's site within minutes.
- Scripts are public — but useless without an active key authorized for that domain.
- Enterprise / partner keys — permanent lifetime keys are issued by IDEnforcer admin; they never expire but remain domain-bound and can be revoked.
Markup — protect any text field
Tag the displayed value only. Labels, headings, and public fields stay unmarked.
Basic example
<label>License number</label>
<span data-protected>123456789</span>
<label>Name</label>
<span>John Doe</span>
Tables, cards, and lists
<td data-protected>01/01/1985</td>
<div class="record-value" data-protected>123 Main Street</div>
<li>Account: <span data-protected>ACC-99281</span></li>
Custom selector
<span class="vs-sensitive">secret-value</span>
ViewShield.init({ licenseKey: "VS-XXXX-XXXX-XXXX", protectedSelector: ".vs-sensitive" });
Recommended CSS
Use the standard stylesheet so protected fields match the live demo (font size, weight, and layout).
<link rel="stylesheet" href="https://idenforcer.com/viewshield/includes/viewshield-protected.css">
<link rel="stylesheet" href="/viewshield/includes/viewshield-protected.css">
Download integration files
If you host ViewShield on your own server instead of the CDN, download the bundle with the engine scripts and includes/ folder:
Download viewshield-integration.zip
TemporalTileEngine.js+ViewShieldV5.js— protection engineincludes/viewshield-protected.css— standard field stylingincludes/viewshield-defaults.js— demo-matched init defaultsincludes/viewshield-init.sample.js— copy, set your license key, and load
<span data-protected> or call ViewShield.refresh() after rendering search results.Light & dark mode
ViewShield ships with two presets that share the same compact overlay (tight text band, tile-area static, tuned capture resistance). Pick the one that matches your page background.
| Preset | Use when | Protected text |
|---|---|---|
ViewShieldPresets.resolve("dark") | Dark dashboards, IDEnforcer Cloud | White on dark panel |
ViewShieldPresets.resolve("light") | White/light cards, print-style pages | Dark on white panel |
1. Set the CSS theme on <html>
<!-- Match your page — controls host field text color -->
<html lang="en" data-viewshield-theme="dark">
2. Load presets and initialize
<link rel="stylesheet" href="/viewshield/includes/viewshield-protected.css">
<script src="/viewshield/TemporalTileEngine.js"></script>
<script src="/viewshield/ViewShieldV5.js"></script>
<script src="/viewshield/includes/viewshield-defaults.js"></script>
<script>
document.documentElement.setAttribute("data-viewshield-theme", "dark");
ViewShield.init(Object.assign({}, ViewShieldPresets.resolve("dark"), {
licenseKey: "VS-XXXX-XXXX-XXXX"
}));
</script>
<link rel="stylesheet" href="/viewshield/includes/viewshield-protected.css">
<script src="/viewshield/TemporalTileEngine.js"></script>
<script src="/viewshield/ViewShieldV5.js"></script>
<script src="/viewshield/includes/viewshield-defaults.js"></script>
<script>
document.documentElement.setAttribute("data-viewshield-theme", "light");
ViewShield.init(Object.assign({}, ViewShieldPresets.resolve("light"), {
licenseKey: "VS-XXXX-XXXX-XXXX"
}));
</script>
paletteOverride.paper to match your card background (RGB). The live demo uses #0f172a; IDEnforcer Cloud uses #1e2432.IDEnforcer Cloud System
Cloud tenants toggle Settings → ViewShield → Display mode (Light / Dark). No code changes required — the engine preset updates automatically.
Peek to read (hover / tap)
Presets enable peekOnHover: true and peekOnClickMs: 2000. Staff see clear text while hovering (desktop) or for 2 seconds after tap (mobile). Protection resumes automatically.
Configuration
All options are passed to ViewShield.init({ … }). Use ViewShieldPresets.resolve("light") or "dark" for recommended settings, or pass only licenseKey for engine defaults (compact light overlay).
| Option | Default | Description |
|---|---|---|
licenseKey | required | Your subscription key from checkout. Without it ViewShield will not start. |
protectedSelector | "[data-protected]" | CSS selector for elements to protect. |
peekOnHover | false | true — hover to reveal clear text (desktop). |
peekOnClickMs | 0 | Tap/click reveal duration in ms (e.g. 2000 for mobile). |
theme | "light" | "light" or "dark". Use presets instead of tuning manually. |
compactOverlay | true | Tight text band — static on a small area around glyphs, not a bulky box. |
overlayRegionMarginX / Y | 2 / 1 | CSS px margin for tile static region (compact mode). |
inkPolarity | "dark" | Set "light" for white text on dark panels (dark preset). |
paletteOverride | optional | Match paper / ink to your panel colors (especially dark mode). |
mode | "extreme" | Preset: minimal, light, standard, moderate, elevated, high, strong, extreme, ultra, maximum. |
affectPercent | from mode | Override with exact % (5–65). |
tileSize | 1.75 | CSS pixels. Supported: 1, 1.5, 1.75, 2, 3, 4, 8, 16. |
tileMode | "random" | checkerboard, random, wave, spiral, edgeFocus. |
watermark | true | Session timestamp watermark. |
temporalNoise | true | Per-frame noise in protected zones. |
ocrProtection | true | Glyph-bound OCR disruption. |
userId | "anonymous" | Optional. Your app’s logged-in user ID (database ID, username, etc.) — not issued by IDEnforcer. Omit if you don’t track users. |
sessionId | auto | Optional. Your app’s session or page-view ID (session_id(), JWT, etc.). Auto-generated if omitted. |
Built-in defaults (override only if needed)
Pass only licenseKey for demo-matched settings. Include extra options below only when you want to change them:
ViewShield.init({
licenseKey: "VS-XXXX-XXXX-XXXX",
protectedSelector: "[data-protected]",
userId: String(currentUser.id), // optional — your auth user ID
sessionId: currentUser.sessionToken // optional — your session token
});
JavaScript API
| Method | Description |
|---|---|
ViewShield.init(config) | Start protection. Re-init stops the previous instance. |
ViewShield.destroy() | Stop engine and remove overlays. Call on SPA route change or logout. |
ViewShield.refresh() | Re-scan DOM for new or changed protected elements. |
ViewShield.getMetrics() | Live readability, protection, OCR resistance, and fps. |
ViewShield.getLicenseStatus() | Whether the current license is valid, expiry, and last error message. |
ViewShield.getStatus() | Version, zone count, config snapshot, session info. |
ViewShield.setMode(mode) | Change strength preset at runtime. |
ViewShield.setAffectPercent(n) | Change exact affect % at runtime. |
ViewShield.setTileMode(mode) | Change tile pattern at runtime. |
// After AJAX loads new records:
fetch("/api/record/123").then(function (r) { return r.json(); }).then(function (data) {
document.getElementById("license").textContent = data.license;
ViewShield.refresh();
});
Dynamic & single-page apps
- Initial load: call
ViewShield.init()after protected content is in the DOM. - Content updates: call
ViewShield.refresh()after inserting or changing text. - Navigation away: call
ViewShield.destroy()before unmounting.
React
useEffect(function () {
ViewShield.init({ licenseKey: "VS-XXXX-XXXX-XXXX", protectedSelector: "[data-protected]", userId: String(user.id), sessionId: user.sessionToken });
return function () { ViewShield.destroy(); };
}, [user.id]);
useEffect(function () { ViewShield.refresh(); }, [record]);
PHP / server-rendered
<span data-protected><?= htmlspecialchars($license) ?></span>
<script src="https://idenforcer.com/viewshield/TemporalTileEngine.js"></script>
<script src="https://idenforcer.com/viewshield/ViewShieldV5.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
ViewShield.init({
licenseKey: "<?= htmlspecialchars($viewshieldLicenseKey) ?>",
protectedSelector: "[data-protected]",
userId: "<?= (int)($_SESSION['user_id'] ?? 0) ?>",
sessionId: "<?= session_id() ?>"
});
});
</script>
Content Security Policy
If your site uses CSP, allow scripts from IDEnforcer:
script-src 'self' https://idenforcer.com;
ViewShield does not require 'unsafe-eval'. Move init code to an external file on your origin to avoid 'unsafe-inline'.
Hosted files
Load these two files in order:
https://idenforcer.com/viewshield/TemporalTileEngine.jshttps://idenforcer.com/viewshield/ViewShieldV5.js
Version 5.0.0 · Default: Extreme 53% · 1.75×1.75 tiles · Random · ProSol watermark
License: $4.99/mo or $53.89/yr (10% annual discount) · Purchase
Live preview
Protected fields on this page — try photographing your screen vs. reading live.