html-ad-generator-mcp
Version:
MCP server for generating HTML ad templates from JSON input for Google Ads and Meta Ads
347 lines • 22.3 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Google Ads Showcase - Interactive Demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<style>
:root{--primary-color:#4285F4;--secondary-color:#34A853;--accent-color:#EA4335;--light-bg:#F8F9FA;--dark-text:#202124}
body{font-family:'Google Sans',Roboto,Arial,sans-serif;color:var(--dark-text);background-color:#fff;padding-top:20px}
.nav-tabs .nav-link{color:#5f6368;font-weight:500;border:none;padding:12px 24px;margin-right:5px;border-radius:8px 8px 0 0}
.nav-tabs .nav-link:hover{color:var(--primary-color);background-color:rgba(66,133,244,0.1)}
.nav-tabs .nav-link.active{color:var(--primary-color);font-weight:600;background-color:white;border-bottom:3px solid var(--primary-color)}
.tab-content{padding:30px;border:1px solid #e0e0e0;border-radius:0 0 8px 8px;background-color:white;box-shadow:0 2px 10px rgba(0,0,0,0.05)}
.ad-preview{border:1px solid #dadce0;border-radius:8px;padding:16px;margin-bottom:30px;background-color:white;box-shadow:0 1px 6px rgba(32,33,36,.28);transition:transform 0.2s,box-shadow 0.2s}
.ad-preview:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(32,33,36,.15)}
.search-ad-headline{color:#1a0dab;font-size:18px;line-height:1.4;margin-bottom:4px;cursor:pointer;text-decoration:underline}
.search-ad-headline:hover{color:#1a0dab}
.search-ad-description{color:#545454;font-size:14px;line-height:1.4;margin-bottom:4px}
.search-ad-url{color:#006621;font-size:14px}
.display-ad{border:1px solid #dadce0;border-radius:8px;overflow:hidden;margin-bottom:30px;background-color:white;box-shadow:0 1px 6px rgba(32,33,36,.28);max-width:300px}
.display-ad-image{width:100%;height:250px;object-fit:cover}
.display-ad-content{padding:16px}
.display-ad-headline{font-size:18px;font-weight:600;margin-bottom:8px;color:var(--dark-text)}
.display-ad-description{font-size:14px;color:#545454;margin-bottom:12px}
.display-ad-business{font-size:12px;color:#006621}
.ad-info-card{background-color:var(--light-bg);border-radius:8px;padding:20px;margin-bottom:20px}
.ad-info-card h5{color:var(--primary-color);margin-bottom:15px}
.character-count{font-size:12px;color:#5f6368;text-align:right;margin-top:4px}
.character-count.danger{color:var(--accent-color)}
.form-control:focus{border-color:var(--primary-color);box-shadow:0 0 0 0.2rem rgba(66,133,244,0.25)}
.btn-primary{background-color:var(--primary-color);border-color:var(--primary-color)}
.btn-primary:hover{background-color:#3367d6;border-color:#3367d6}
.component-label{font-weight:600;color:#5f6368;margin-bottom:8px;font-size:14px}
.toast-container{position:fixed;top:20px;right:20px;z-index:1050}
.headline-dropdown{margin-bottom:10px}
/* Editable dropdown (single field with options) */
.editable-dropdown{position:relative}
.editable-dropdown .editable-dropdown-toggle{position:absolute;right:10px;top:50%;transform:translateY(-50%);cursor:pointer;color:#666;font-size:12px}
.editable-dropdown .dropdown-options{position:absolute;top:100%;left:0;right:0;background:#fff;border:1px solid #ddd;border-top:none;border-radius:0 0 6px 6px;max-height:180px;overflow-y:auto;z-index:1000;display:none}
.editable-dropdown .dropdown-option{padding:10px;cursor:pointer;font-size:14px;border-bottom:1px solid #f0f0f0;background:#fff}
.editable-dropdown .dropdown-option:hover{background:#f8f9fa}
.editable-dropdown .dropdown-option:last-child{border-bottom:none}
.page-header{display:flex;justify-content:center;align-items:center;margin-bottom:30px;padding:0 15px}
.page-title{font-size:2rem;font-weight:700;color:var(--dark-text);margin:0;text-align:center}
</style>
</head>
<body>
<div class="page-header"><h1 class="page-title">Google Ads Interactive Showcase</h1></div>
<div class="container mb-5">
<ul class="nav nav-tabs" id="adTabs" role="tablist">
<li class="nav-item" role="presentation"><button class="nav-link active" id="search-tab" data-bs-toggle="tab" data-bs-target="#search" type="button" role="tab" aria-controls="search" aria-selected="true"><i class="bi bi-search"></i> Search Ads</button></li>
<li class="nav-item" role="presentation"><button class="nav-link" id="display-tab" data-bs-toggle="tab" data-bs-target="#display" type="button" role="tab" aria-controls="display" aria-selected="false"><i class="bi bi-image"></i> Display Ads</button></li>
</ul>
<div class="tab-content" id="adTabsContent">
<!-- Search Ads Tab -->
<div class="tab-pane fade show active" id="search" role="tabpanel" aria-labelledby="search-tab">
<div class="row">
<div class="col-lg-6">
<h4 class="mb-4">Search Ad Preview</h4>
<div class="ad-preview" id="search-ad-preview">
<div class="search-ad-headline" id="search-preview-headline">Premium Running Shoes - Lightweight & Comfortable - Shop Now - 50% Off</div>
<div class="search-ad-description" id="search-preview-description-1">Experience ultimate comfort with our premium running shoes. Perfect for all terrains.</div>
<div class="search-ad-description" id="search-preview-description-2">Limited time offer: Buy 1 get 1 free. Free shipping on orders over $50.</div>
<div class="search-ad-url" id="search-preview-url">www.example.com</div>
</div>
<div class="ad-info-card">
<h5>How It Works</h5>
<p>Search ads appear on Google search results pages when users search for specific keywords. They consist of up to three headlines and two descriptions.</p>
<p>Edit the fields on the right to see real-time changes in the ad preview.</p>
</div>
</div>
<div class="col-lg-6">
<div class="ad-info-card">
<h5>Search Ad Components</h5>
<div class="mb-3">
<div class="component-label">Headline 1 (Primary Keyword)</div>
<div class="editable-dropdown">
<input type="text" class="form-control" id="search-headline-1" value="Premium Running Shoes" maxlength="30" oninput="updateSearchAd()">
<div class="editable-dropdown-toggle" onclick="toggleDropdown('search-headline-1-options')">▼</div>
<div class="dropdown-options" id="search-headline-1-options">
<div class="dropdown-option" onclick="selectEditableOption('search-headline-1', this)">Premium Running Shoes</div>
<div class="dropdown-option" onclick="selectEditableOption('search-headline-1', this)">Best Athletic Footwear</div>
<div class="dropdown-option" onclick="selectEditableOption('search-headline-1', this)">Top Rated Sneakers</div>
</div>
</div>
<div class="character-count" id="search-headline-1-count">20/30</div>
</div>
<div class="mb-3">
<div class="component-label">Headline 2 (Unique Value)</div>
<div class="editable-dropdown">
<input type="text" class="form-control" id="search-headline-2" value="Lightweight & Comfortable" maxlength="30" oninput="updateSearchAd()">
<div class="editable-dropdown-toggle" onclick="toggleDropdown('search-headline-2-options')">▼</div>
<div class="dropdown-options" id="search-headline-2-options">
<div class="dropdown-option" onclick="selectEditableOption('search-headline-2', this)">Lightweight & Comfortable</div>
<div class="dropdown-option" onclick="selectEditableOption('search-headline-2', this)">Durable & Stylish</div>
<div class="dropdown-option" onclick="selectEditableOption('search-headline-2', this)">Perfect Fit Guaranteed</div>
</div>
</div>
<div class="character-count" id="search-headline-2-count">23/30</div>
</div>
<div class="mb-3">
<div class="component-label">Headline 3 (Call to Action)</div>
<div class="editable-dropdown">
<input type="text" class="form-control" id="search-headline-3" value="Shop Now - 50% Off" maxlength="30" oninput="updateSearchAd()">
<div class="editable-dropdown-toggle" onclick="toggleDropdown('search-headline-3-options')">▼</div>
<div class="dropdown-options" id="search-headline-3-options">
<div class="dropdown-option" onclick="selectEditableOption('search-headline-3', this)">Shop Now - 50% Off</div>
<div class="dropdown-option" onclick="selectEditableOption('search-headline-3', this)">Limited Time Offer</div>
<div class="dropdown-option" onclick="selectEditableOption('search-headline-3', this)">Free Shipping Today</div>
</div>
</div>
<div class="character-count" id="search-headline-3-count">18/30</div>
</div>
<div class="mb-3">
<div class="component-label">Description 1</div>
<div class="editable-dropdown">
<textarea class="form-control" id="search-description-1" rows="2" maxlength="90" oninput="updateSearchAd()">Experience ultimate comfort with our premium running shoes. Perfect for all terrains.</textarea>
<div class="editable-dropdown-toggle" onclick="toggleDropdown('search-description-1-options')">▼</div>
<div class="dropdown-options" id="search-description-1-options">
<div class="dropdown-option" onclick="selectEditableOption('search-description-1', this)">Experience ultimate comfort with our premium running shoes. Perfect for all terrains.</div>
<div class="dropdown-option" onclick="selectEditableOption('search-description-1', this)">Discover the perfect blend of style and performance. Shop our collection today.</div>
<div class="dropdown-option" onclick="selectEditableOption('search-description-1', this)">Engineered for athletes who demand the best. Try them risk-free for 30 days.</div>
</div>
</div>
<div class="character-count" id="search-description-1-count">84/90</div>
</div>
<div class="mb-3">
<div class="component-label">Description 2</div>
<div class="editable-dropdown">
<textarea class="form-control" id="search-description-2" rows="2" maxlength="90" oninput="updateSearchAd()">Limited time offer: Buy 1 get 1 free. Free shipping on orders over $50.</textarea>
<div class="editable-dropdown-toggle" onclick="toggleDropdown('search-description-2-options')">▼</div>
<div class="dropdown-options" id="search-description-2-options">
<div class="dropdown-option" onclick="selectEditableOption('search-description-2', this)">Limited time offer: Buy 1 get 1 free. Free shipping on orders over $50.</div>
<div class="dropdown-option" onclick="selectEditableOption('search-description-2', this)">Rated 4.8/5 stars by over 10,000 customers. Join our satisfied community.</div>
<div class="dropdown-option" onclick="selectEditableOption('search-description-2', this)">Available in multiple colors and sizes. 100% satisfaction guarantee.</div>
</div>
</div>
<div class="character-count" id="search-description-2-count">86/90</div>
</div>
</div>
<div class="ad-info-card">
<h5>Best Practices</h5>
<ul>
<li>Focus on clarity and match user intent</li>
<li>Use main keywords prominently</li>
<li>Add strong CTAs (Buy Now, Call Today, etc.)</li>
<li>Include unique selling points and qualifiers</li>
<li>Avoid excessive punctuation or capitalization</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Display Ads Tab -->
<div class="tab-pane fade" id="display" role="tabpanel" aria-labelledby="display-tab">
<div class="row">
<div class="col-lg-6">
<h4 class="mb-4">Display Ad Preview</h4>
<div class="display-ad">
<img src="https://picsum.photos/seed/fashion123/600/600.jpg" alt="Display Ad Image" class="display-ad-image" id="display-preview-image">
<div class="display-ad-content">
<div class="display-ad-headline" id="display-preview-headline">Summer Collection</div>
<div class="display-ad-headline" id="display-preview-long-headline">Discover Our New Summer Collection - Up to 60% Off</div>
<div class="display-ad-description" id="display-preview-description">Refresh your wardrobe with our stylish summer collection. Limited time offer.</div>
<div class="display-ad-business" id="display-preview-business">FashionHub</div>
</div>
</div>
<div class="ad-info-card">
<h5>How It Works</h5>
<p>Display ads appear on websites across the Google Display Network. They combine visual elements with text to attract attention and drive engagement.</p>
<p>Edit the fields on the right to see real-time changes in the ad preview.</p>
</div>
</div>
<div class="col-lg-6">
<div class="ad-info-card">
<h5>Display Ad Components</h5>
<div class="mb-3">
<div class="component-label">Headline</div>
<div class="editable-dropdown">
<input type="text" class="form-control" id="display-headline" value="Summer Collection" maxlength="30" oninput="updateDisplayAd()">
<div class="editable-dropdown-toggle" onclick="toggleDropdown('display-headline-options')">▼</div>
<div class="dropdown-options" id="display-headline-options">
<div class="dropdown-option" onclick="selectEditableOption('display-headline', this)">Summer Collection</div>
<div class="dropdown-option" onclick="selectEditableOption('display-headline', this)">Winter Sale</div>
<div class="dropdown-option" onclick="selectEditableOption('display-headline', this)">New Arrivals</div>
</div>
</div>
<div class="character-count" id="display-headline-count">18/30</div>
</div>
<div class="mb-3">
<div class="component-label">Long Headline</div>
<div class="editable-dropdown">
<input type="text" class="form-control" id="display-long-headline" value="Discover Our New Summer Collection - Up to 60% Off" maxlength="90" oninput="updateDisplayAd()">
<div class="editable-dropdown-toggle" onclick="toggleDropdown('display-long-headline-options')">▼</div>
<div class="dropdown-options" id="display-long-headline-options">
<div class="dropdown-option" onclick="selectEditableOption('display-long-headline', this)">Discover Our New Summer Collection - Up to 60% Off</div>
<div class="dropdown-option" onclick="selectEditableOption('display-long-headline', this)">Winter Sale - Save Up to 70% on All Items</div>
<div class="dropdown-option" onclick="selectEditableOption('display-long-headline', this)">Check Out Our Latest Arrivals - Free Returns</div>
</div>
</div>
<div class="character-count" id="display-long-headline-count">58/90</div>
</div>
<div class="mb-3">
<div class="component-label">Description</div>
<div class="editable-dropdown">
<textarea class="form-control" id="display-description" rows="2" maxlength="90" oninput="updateDisplayAd()">Refresh your wardrobe with our stylish summer collection. Limited time offer.</textarea>
<div class="editable-dropdown-toggle" onclick="toggleDropdown('display-description-options')">▼</div>
<div class="dropdown-options" id="display-description-options">
<div class="dropdown-option" onclick="selectEditableOption('display-description', this)">Refresh your wardrobe with our stylish summer collection. Limited time offer.</div>
<div class="dropdown-option" onclick="selectEditableOption('display-description', this)">Stay warm this winter with our cozy collection. Huge discounts available now.</div>
<div class="dropdown-option" onclick="selectEditableOption('display-description', this)">Be the first to get our newest arrivals. Exclusive styles just for you.</div>
</div>
</div>
<div class="character-count" id="display-description-count">84/90</div>
</div>
<div class="mb-3">
<div class="component-label">Business Name</div>
<div class="editable-dropdown">
<input type="text" class="form-control" id="display-business" value="FashionHub" maxlength="25" oninput="updateDisplayAd()">
<div class="editable-dropdown-toggle" onclick="toggleDropdown('display-business-options')">▼</div>
<div class="dropdown-options" id="display-business-options">
<div class="dropdown-option" onclick="selectEditableOption('display-business', this)">FashionHub</div>
<div class="dropdown-option" onclick="selectEditableOption('display-business', this)">StyleStudio</div>
<div class="dropdown-option" onclick="selectEditableOption('display-business', this)">TrendWear</div>
</div>
</div>
<div class="character-count" id="display-business-count">9/25</div>
</div>
</div>
<div class="ad-info-card">
<h5>Best Practices</h5>
<ul>
<li>Make headlines attention-grabbing but clear</li>
<li>Prioritize readability; avoid jargon or dense text</li>
<li>Visually align image/creative with brand and copy</li>
<li>Use high-quality, relevant images</li>
<li>Include a clear call to action</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="toast-container"></div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded',function(){updateAllCharacterCounts()});
function updateAllCharacterCounts(){
updateCharacterCount('search-headline-1',30);
updateCharacterCount('search-headline-2',30);
updateCharacterCount('search-headline-3',30);
updateCharacterCount('search-description-1',90);
updateCharacterCount('search-description-2',90);
updateCharacterCount('display-headline',30);
updateCharacterCount('display-long-headline',90);
updateCharacterCount('display-description',90);
updateCharacterCount('display-business',25);
}
function updateCharacterCount(inputId,maxLength){
const input=document.getElementById(inputId);
const countElement=document.getElementById(inputId+'-count');
if(input && countElement){
const length=input.value.length;
countElement.textContent=`${length}/${maxLength}`;
countElement.classList.remove('danger');
if(length>=maxLength)countElement.classList.add('danger');
}
}
function handleFieldChange(inputId){
const selectElement=document.getElementById(inputId+'-select');
const inputElement=document.getElementById(inputId);
const selectedValue=selectElement.value;
inputElement.value=selectedValue;
if(inputId.startsWith('search-headline') || inputId.startsWith('search-description'))updateSearchAd();
else if(inputId.startsWith('display-headline') || inputId.startsWith('display-description') || inputId.startsWith('display-business'))updateDisplayAd();
updateCharacterCount(inputId, inputElement.maxLength);
}
function updateSearchAd(){
updateCharacterCount('search-headline-1',30);
updateCharacterCount('search-headline-2',30);
updateCharacterCount('search-headline-3',30);
updateCharacterCount('search-description-1',90);
updateCharacterCount('search-description-2',90);
const headline1=document.getElementById('search-headline-1').value;
const headline2=document.getElementById('search-headline-2').value;
const headline3=document.getElementById('search-headline-3').value;
const description1=document.getElementById('search-description-1').value;
const description2=document.getElementById('search-description-2').value;
document.getElementById('search-preview-headline').textContent=`${headline1} - ${headline2} - ${headline3}`;
document.getElementById('search-preview-description-1').textContent=description1;
document.getElementById('search-preview-description-2').textContent=description2;
document.getElementById('search-preview-url').textContent='www.example.com';
}
function updateDisplayAd(){
updateCharacterCount('display-headline',30);
updateCharacterCount('display-long-headline',90);
updateCharacterCount('display-description',90);
updateCharacterCount('display-business',25);
const headline=document.getElementById('display-headline').value;
const longHeadline=document.getElementById('display-long-headline').value;
const description=document.getElementById('display-description').value;
const business=document.getElementById('display-business').value;
document.getElementById('display-preview-headline').textContent=headline;
document.getElementById('display-preview-long-headline').textContent=longHeadline;
document.getElementById('display-preview-description').textContent=description;
document.getElementById('display-preview-business').textContent=business;
}
// Editable dropdown helpers (single field + options)
function toggleDropdown(optionsId){
document.querySelectorAll('.dropdown-options').forEach(function(drop){
if(drop.id!==optionsId){drop.style.display='none'}
});
const options=document.getElementById(optionsId);
if(options){options.style.display=options.style.display==='block'?'none':'block'}
}
function selectEditableOption(inputId, optionElement){
const input=document.getElementById(inputId);
if(!input)return;
input.value=optionElement.textContent;
const parent=optionElement.parentElement; if(parent) parent.style.display='none';
if(inputId.startsWith('search-')){updateSearchAd();}
else if(inputId.startsWith('display-')){updateDisplayAd();}
updateCharacterCount(inputId, input.maxLength);
input.focus();
}
// Close dropdowns on outside click
document.addEventListener('click',function(event){
if(!event.target.closest('.editable-dropdown')){
document.querySelectorAll('.dropdown-options').forEach(function(drop){drop.style.display='none'});
}
});
function showToast(message,type='info'){
const toastContainer=document.querySelector('.toast-container');
const toastId='toast-'+Date.now();
const toastHtml=`<div id="${toastId}" class="toast align-items-center text-white bg-${type==='success'?'success':'primary'} border-0" role="alert" aria-live="assertive" aria-atomic="true"><div class="d-flex"><div class="toast-body">${message}</div><button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button></div></div>`;
toastContainer.insertAdjacentHTML('beforeend',toastHtml);
const toastElement=document.getElementById(toastId);
const toast=new bootstrap.Toast(toastElement,{autohide:true,delay:3000});
toast.show();
toastElement.addEventListener('hidden.bs.toast',function(){toastElement.remove()});
}
</script>
</body>
</html>