# Smart User Scripts

> Run a script on matching pages only - the userscript model, inside your app.

- **Applies to:** AppMint and Appwright
- **Source:** the Integration Guide shipped inside the app; this page is generated from it.
- **HTML:** https://freewebtoapk.com/docs/smart-user-scripts

Per-Site Scripts with URL Matching & Timing (like Greasemonkey)

### 1. What Are Smart User Scripts?

Smart User Scripts are individual named scripts - each with its own:  
🌐 URL match patterns  (which pages to run on)  
⏱ Run-at timing  (before, during or after load)  
✅ Enable/Disable toggle

They work like Greasemonkey or Tampermonkey in desktop browsers - but built right into your app.

✅ Perfect for:

- Auto-login ONLY on the /login page
- Hide ads ONLY on article pages (https://news.com/article/*)
- Watch DOM changes with MutationObserver
- Inject before page renders (document-start) to avoid flash

Key difference from Quick Injection:  
Quick Injection = same CSS/JS on ALL pages  
Smart User Scripts = per-script, per-URL, per-timing control

### 2. Where to Find It

Step 4 (Permissions) → scroll down → 🤖 Smart User Scripts card.

Tap '+ Add' to create a new script. Each script has:

- Name - shown in the manager list
- URL Match Patterns - one per line (supports * wildcard)
- Run At - document-end / document-start / document-idle
- Code - your JavaScript
- Enabled toggle

Tap any row to edit or delete a script.

### 3. URL Match Pattern Examples

Patterns control which pages the script runs on. Use * as a wildcard:

```
# Run on every page of every site
*://*/*

# Run only on example.com (any path)
https://example.com/*

# Run on ALL pages of ANY .com domain
https://*.com/*

# Run only on the /login path
https://example.com/login
https://example.com/login/*

# Run on news article pages
https://news.example.com/article/*
```

### 4. Run-At Timing Explained

- document-end (default)

Runs AFTER the page finishes loading. Safe, most compatible. Use for hiding elements, adding buttons, tracking.

- document-start ⚡ (advanced)

Runs BEFORE the page renders. Injects script into the raw HTML via shouldInterceptRequest. Removes CSP headers. Use for dark-mode CSS or forcing viewport before layout paint.

- document-idle ⏱

Runs 1.5 seconds after page load. Good for catching late-loading AJAX content or modals that appear after a delay.

### 5. Example 1: Auto-Login on /login Only

Match: https://myapp.com/login  
Run-at: document-end

```
// Auto-fill login form
(function() {
  var email = document.querySelector('input[type=email], input[name=email]');
  var pass  = document.querySelector('input[type=password]');
  if (email) email.value = 'user@example.com';
  if (pass)  pass.value  = 'mypassword';
  // Uncomment to auto-submit:
  // var form = document.querySelector('form');
  // if (form) form.submit();
})();
```

### 6. Example 2: Hide Paywalls on Article Pages

Match: https://news.site.com/article/*  
Run-at: document-end

```
// Hide paywall overlay and restore scroll
(function() {
  var overlay = document.querySelector('.paywall-overlay, .metered-content, #paywall');
  if (overlay) overlay.remove();
  document.body.style.overflow = 'auto';
  document.documentElement.style.overflow = 'auto';
})();
```

### 7. Example 3: Watch Dynamic Content (MutationObserver)

Match: *://*/*  
Run-at: document-end  
For elements that appear AFTER page load (lazy-loaded modals, ads):

```
// Remove any modal/popup that appears dynamically
(function() {
  var sel = '.modal, .popup, .overlay, [class*="modal"], [class*="popup"]';
  // Remove existing ones first
  document.querySelectorAll(sel).forEach(function(el) { el.remove(); });
  // Watch for new ones
  var obs = new MutationObserver(function() {
    document.querySelectorAll(sel).forEach(function(el) { el.remove(); });
  });
  obs.observe(document.body, { childList: true, subtree: true });
  // Stop watching after 30 s to save battery
  setTimeout(function() { obs.disconnect(); }, 30000);
})();
```

### 8. Example 4: Force Dark Mode Before Render (document-start)

Match: *://*/*  
Run-at: document-start  
Injects CSS before the page paints - no white flash:

```
// Inject dark theme before page renders
(function() {
  var s = document.createElement('style');
  s.id = '__force_dark__';
  s.textContent = [
    'html { filter: invert(1) hue-rotate(180deg) !important; }',
    'img,video,canvas,svg { filter: invert(1) hue-rotate(180deg) !important; }'
  ].join('\
');
  (document.head || document.documentElement).appendChild(s);
})();
```

### 9. Example 5: Custom Analytics / Event Tracking

Match: https://myshop.com/*  
Run-at: document-idle  
Send custom events after the page fully settles:

```
// Track page views + button clicks
(function() {
  // Page view
  console.log('[Analytics] Page: ' + location.href);

  // Track all CTA button clicks
  document.querySelectorAll('button, .btn, a[href]').forEach(function(el) {
    el.addEventListener('click', function() {
      console.log('[Analytics] Clicked: ' + (el.textContent || el.href));
      // Replace with your own tracker call, e.g. gtag('event', ...)
    });
  });
})();
```

### 10. Security & Limitations

⚡ document-start removes Content-Security-Policy headers for the matched page. Only use on sites you own or explicitly trust.

🔒 Same-Origin Policy: JS cannot access cross-origin iframes (PayPal, Stripe, Google login). This is enforced by the browser engine and cannot be bypassed.

📵 HTTPS Only: APIs like geolocation or camera in injected scripts require HTTPS.

✅ Guard against double-run: each script is guarded by a window flag so it runs only once per page.

✅ Works offline: Smart User Scripts also run in ZIP-bundled offline apps.

