Welcome
Select a tab above to begin.
Ads Set
| Campaign Name | Adset Name | Keywords |
|---|
Tip: tap/click any cell to copy it. Shortcuts (Search/Ads Set): Ctrl+E β Export CSV
Ads Copy (Heading)
| Particulars | Ads Copy |
|---|
Shortcut: Ctrl+Shift+E β Export CSV (Headings)
Ads Copy (Description)
| Particulars | Ads Copy |
|---|
Shortcut: Ctrl+Alt+E β Export CSV (Descriptions)
Templates
Load or modify template sets. Changes are saved to localStorage and applied immediately.
On every full page refresh, shipped defaults overwrite stored templates (so you always start clean).
To edit manually: export β change JSON β import.
Logs
| When | Session | Type | Rows | Inputs |
|---|
Help & Notes
What it does
- Generates a 3-column Search table β Campaign Name, Adset Name, Keywords β for the selected Type.
- If the Type defines Ads content, itβs shown in two 2-column tables:
- Ads Copy (Heading) β columns: Particulars | Ads Copy
- Ads Copy (Description) β columns: Particulars | Ads Copy
sectionflag on each Ads row:"section": "heading"or"description". Legacy rows are auto-classified when missing the flag. - Types can differ. Each Type ships its own variables, sample placeholders, Search rows, and Ads rows.
- Inputs are auto-generated from the Typeβs
variableslist (e.g.,BUILDER + PROJECT,CITY) or legacy{{keywordN}}usage. - Works offline. Templates/logs persist in
localStorage; auth state is insessionStorage.
Placeholders & modifiers
- Named placeholders (single braces) map 1:1 to inputs:
{VAR NAME}like{BUILDER + PROJECT},{CITY},{PRICE}. - Legacy placeholders (double braces) support optional modifiers:
{{keyword1}},{{keyword2.lower}},{{keyword3.upper}},{{keyword4.cap}},{{keyword5.slug}}. - Built-ins (double-brace only):
{{today}}(YYYY-MM-DD),{{ts}}(Unix ms). - Missing variables resolve to empty strings. Only variable insertions are transformed; static template text is preserved exactly.
Inline JOIN (multi-value helpers)
- Use
{JOIN:VAR A, VAR B, ...}to render only the variables provided, joined by/(no spaces). Example:{JOIN:TYPOLOGY 1, TYPOLOGY 2, TYPOLOGY 3}β 1/2/3. - JOIN is processed before placeholders are transformed, then variable values are Title-Cased (in Ads) and slashes are tightened (no spaces around
/). - Rows containing JOIN hide unless at least one referenced variable has a value (unless
X: trueis set).
Formatting rules
- Search (variables only):
- Campaign Name β
lowercase_with_underscores - Adset Name β
lowercase_with_underscores - Keywords β lowercase text (spaces preserved)
- Campaign Name β
- Ads Copy:
- Variables β Title Case
- Tighten slashes:
1 / 2 / 3β1/2/3 - JOIN renders only provided variables
- Row hiding:
- Search rows hide if required variables are missing.
- Ads rows hide if required variables are missing or JOIN has no inputs.
- Ads rows with
X: truealways show.
Copy & export
- Click/tap any cell to copy that cell.
- Copy All uses TSV for easy paste into Sheets/Excel.
- Exports:
- Search: CSV (
outputs_search.*) - Ads Copy (Heading): CSV (
ads_headings.*) - Ads Copy (Description): CSV (
ads_descriptions.*)
- Search: CSV (
- Shortcuts:
- Ctrl+E β Export CSV (Search)
- Ctrl+Shift+E β Export CSV (Ads Copy β Headings)
- Ctrl+Alt+E β Export CSV (Ads Copy β Descriptions)
- Ctrl+S β Save log (manual)
- Filenames include an ISO timestamp.
Template JSON format (per Type)
{
"Type X": {
"nickname": "Optional_Friendly_Name",
"columns": ["Campaign Name","Adset Name","Keywords"],
"searchRows": [
{"campaign":"...","adset":"...","keywords":"..."}
],
"adsColumns": ["Particulars","Ads Copy"],
"adsRows": [
{"particular":"...","copy":"...","section":"heading"},
{"particular":"...","copy":"...","section":"description","X": true}
],
"variables": ["..."],
"samples": {"VAR":"..."}
}
}
Authoring prompt (to generate/refresh a Type from tables)
You are helping me maintain JSON templates for my internal Keyword Generator tool.
I may share one or both of these tables (Types can differ; include only what exists):
- Search (3 columns): Campaign Name | Adset Name | Keywords β becomes searchRows
- Ads (2 columns): Particulars | Ads Copy β becomes adsRows
Your tasks:
1) Convert each Search row to: {"campaign":"...","adset":"...","keywords":"..."}
2) Convert each Ads row to: {"particular":"...","copy":"...","section":"heading|description"}
- If the row label is a headline (H1/H2/H3, or numeric variants like "1 - ...", "2 - ..."), set section="heading".
- If itβs a description (e.g., "Description 1"), set section="description".
- Optionally add "X": true to force the row to always show.
3) When a cell shows "1/2/3/4/5/6 BHK", replace it with:
{JOIN:TYPOLOGY 1, TYPOLOGY 2, TYPOLOGY 3, TYPOLOGY 4, TYPOLOGY 5, TYPOLOGY 6}
Keep trailing words outside JOIN (e.g., "{JOIN:...} BHK Apartments").
Formatting & rules:
- Transformations are applied to variables only (not static text).
- Search output (variables only):
β’ Campaign, Adset β lowercase_with_underscores
β’ Keywords β lowercase, spaces preserved
- Ads output:
β’ Variables β Title Case; tighten slashes (1/2/3)
β’ JOIN renders only provided variables: {JOIN:A,B,C} β "A/B/C"
- Row hiding:
β’ Search rows hide if required variables are missing.
β’ Ads rows hide if required variables are missing or if JOIN has no inputs.
β’ Ads rows with "X": true always show.
- Use single-brace placeholders like {BUILDER + PROJECT}, {CITY}, {PRICE}.
- Ensure variables[] and samples{} cover all single-brace placeholders used.
- Return valid JSON only β no extra commentary.
Deployment & Caching Tips
Local / Git / Server
- Local: open
index.htmlvia a local server (or use HTTPS) so clipboard APIs work reliably. - GitHub Pages / static hosts: rely on the version query (
?v=...) on CSS/JS and bumpKG_BUILD_IDeach deploy. - Server (Apache/LiteSpeed/NGINX): prefer cache/security headers on the server. See .htaccess sample below.
If you still see stale files
- DevTools β Network β Disable cache β Hard reload.
- Force a version bump: update
KG_BUILD_IDand the?v=...query on your tags. - Clear host/CDN caches if applicable.
Recommended .htaccess (Apache/LiteSpeed)
# ================================
# Host hardening & no-cache for HTML
# ================================
Options -Indexes
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set Referrer-Policy "no-referrer"
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
Header always set X-Robots-Tag "noindex, noarchive, nosnippet, noimageindex"
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' data:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
Header set Pragma "no-cache"
Header set Expires "0"
RedirectMatch 404 /(?:\.git|\.svn|\.hg|\.DS_Store|Thumbs\.db)(/.*)?$
AddDefaultCharset utf-8
AddType text/javascript .js