UNPKG

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
<!DOCTYPE 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>