Skip to content

🤖 Cannot save fiddle #2351

@silviaNavi

Description

@silviaNavi

Error code

ERRW:0.7:SJ0.7:AS

Were you logged in?

Yes

Your username (if logged in)

silnavi

Your HTML

<h1>QR Dynamic Parameter POC</h1>

  <div class="grid">
    <!-- Left: Show your QR so people can scan it -->
    <div class="card">
      <h2>1) Show your QR</h2>
      <p class="small">Upload your QR image (e.g., the one you attached) so testers can scan it from their phones.</p>
      <input id="file" type="file" accept="image/*" />
      <div id="qrWrap" style="margin-top: 1rem;">
        <img id="qrImg" alt="QR will appear here" />
      </div>
      <p class="muted small">Note: Scanning opens whatever URL is encoded in the QR. To test dynamic parameters, the QR should point to this page (your JSFiddle URL), optionally with <span class="mono">?go=1</span> and/or <span class="mono">&to=...</span>.</p>
    </div>

    <!-- Right: Landing/redirect logic -->
    <div class="card">
      <h2>2) Dynamic redirect</h2>
      <p class="small">This acts as the “landing” that appends dynamic parameters at scan time and forwards to your destination.</p>

      <label for="dest">Destination URL (final target)</label>
      <input id="dest" type="text" placeholder="https://example.com/landing" />

      <div style="margin: 0.5rem 0;">
        <label><input id="preserveAll" type="checkbox" checked /> Preserve all incoming query params</label><br/>
        <label><input id="auto" type="checkbox" /> Auto‑redirect now</label>
      </div>

      <div class="row">
        <button id="build">Build URL</button>
        <button id="go">Redirect now</button>
        <button id="copy">Copy built URL</button>
      </div>

      <details open>
        <summary class="small">Built URL</summary>
        <div id="out" class="mono small break"></div>
      </details>

      <p class="small muted">
        How it works:
        <span class="pill">Copies incoming params (if enabled)</span>
        <span class="pill">Adds src=qr</span>
        <span class="pill">Adds ts=UNIXms</span>
        <span class="pill">Adds rid=random</span>
      </p>

      <details>
        <summary class="small">Tips</summary>
        <ul class="small">
          <li>Pass <span class="mono">?go=1</span> in the URL to auto‑redirect on page load.</li>
          <li>Pass <span class="mono">?to=https://your-target</span> to set the destination from the URL.</li>
          <li>Any other params sent to this page (e.g., <span class="mono">?campaign=Q1&id=42</span>) will be preserved if the checkbox is on.</li>
        </ul>
      </details>
    </div>
  </div>

Your JavaScript

// --- QR display (upload your attached image) ---
    const fileInput = document.getElementById('file');
    const qrImg = document.getElementById('qrImg');
    fileInput.addEventListener('change', (e) => {
      const f = e.target.files?.[0];
      if (!f) return;
      const reader = new FileReader();
      reader.onload = () => { qrImg.src = reader.result; };
      reader.readAsDataURL(f);
    });

    // --- Dynamic parameter landing/redirect ---
    const params = new URLSearchParams(location.search);
    const UI = {
      dest: document.getElementById('dest'),
      auto: document.getElementById('auto'),
      out: document.getElementById('out'),
      preserveAll: document.getElementById('preserveAll'),
      build: document.getElementById('build'),
      go: document.getElementById('go'),
      copy: document.getElementById('copy'),
    };

    // Initialize fields from URL (optional)
    UI.dest.value = params.get('to') || '';
    UI.auto.checked = params.has('go') || params.get('auto') === '1';

    function randId(len = 8) {
      const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
      let s = '';
      crypto.getRandomValues(new Uint8Array(len)).forEach(v => s += alphabet[v % alphabet.length]);
      return s;
    }

    function buildRedirectURL() {
      const base = UI.dest.value.trim() || 'https://example.com/landing';
      let dest;
      try {
        dest = new URL(base);
      } catch {
        alert('Destination URL is invalid.');
        return null;
      }

      // Copy incoming query params (except control keys)
      if (UI.preserveAll.checked) {
        for (const [k, v] of params.entries()) {
          if (['to', 'go', 'auto'].includes(k)) continue; // control keys
          dest.searchParams.set(k, v);
        }
      }

      // Add dynamic params
      dest.searchParams.set('src', 'qr');
      dest.searchParams.set('ts', Date.now().toString());
      dest.searchParams.set('rid', randId());

      return dest.toString();
    }

    function refreshOut() {
      const url = buildRedirectURL();
      UI.out.textContent = url || '';
    }

    UI.build.addEventListener('click', refreshOut);

    UI.go.addEventListener('click', () => {
      const url = buildRedirectURL();
      if (url) location.href = url;
    });

    UI.copy.addEventListener('click', async () => {
      const url = buildRedirectURL();
      if (!url) return;
      try {
        await navigator.clipboard.writeText(url);
        UI.copy.textContent = 'Copied!';
        setTimeout(() => (UI.copy.textContent = 'Copy built URL'), 800);
      } catch {
        prompt('Copy the URL:', url);
      }
    });

    // On load: build output
    refreshOut();

    // Auto-redirect if requested
    if (UI.auto.checked) {
      const url = buildRedirectURL();
      if (url) location.replace(url);
    }

Your CSS

:root { color-scheme: light dark; }
  body { font-family: system-ui, Arial, sans-serif; margin: 2rem; line-height: 1.45; }
  h1 { font-size: 1.25rem; margin: 0 0 1rem; }
  .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start; }
  .card { border: 1px solid #ccc; border-radius: 8px; padding: 1rem; }
  label { display: block; margin: 0.5rem 0 0.25rem; font-weight: 600; }
  input[type="text"] { width: 100%; padding: 0.5rem; }
  button { padding: 0.5rem 0.75rem; margin-right: 0.5rem; }
  code, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
  .muted { color: #666; }
  img { max-width: 100%; height: auto; }
  .row { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
  .small { font-size: 0.9rem; }
  .pill { display: inline-block; border: 1px solid #ccc; border-radius: 999px; padding: 0.1rem 0.5rem; margin: 0.1rem; }
  .good { color: #065f46; }
  .warn { color: #92400e; }
  details { margin-top: 0.5rem; }
  .break { overflow-wrap: anywhere; }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions