Pop-up/Banner Announcements

Hi

Is there a way to add a pop-up/banner announcement when users log in to the app to announce a new feature/update? Softr do this when there’s been an update but I can’t find where to create it.

Thanks :slightly_smiling_face: :folded_hands:

Hey!

You can have one of those on your app. Check out this:

Ohhhh perfect.

Thank you :slightly_smiling_face:

Hi @acjnas this works a treat, thank you so much :slightly_smiling_face: . Is there a way to keep the PopUp closed once the user has closed it? It keeps reappearing.

Do You want that code. I’ve solved this.

1 Like

Hi @jaspijk, thank you for the offer, I’ve managed to solve it. I appreciate you reaching out :slightly_smiling_face:

1 Like

Hi @jaspijk , would you mind sharing the code to keep the PopUp closed once the user has closed it?

Softr News Popup - Once Per Session
.popup-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 999; display: none; }
  .popup-container {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    border-radius: 20px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    width: 500px;
    max-width: 90vw;
    z-index: 1000;
    padding: 30px 30px 20px;
    font-family: sans-serif;
    display: none;
  }

  .popup-container.show {
    display: block;
  }

  .popup-overlay.show {
    display: block;
  }

  .popup-close {
    position: absolute;
    top: 16px;
    right: 20px;
    font-size: 22px;
    font-weight: bold;
    color: #999;
    cursor: pointer;
    transition: color 0.2s;
  }

  .popup-close:hover {
    color: #666;
  }

  .popup-header {
    font-size: 24px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 20px;
  }

  .popup-slide {
    display: none;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .popup-slide.active {
    display: flex;
  }

  .popup-image {
    width: 100%;
    max-width: 260px;
    margin-bottom: 20px;
    border-radius: 12px;
  }

  .popup-date {
    font-size: 12px;
    color: #999;
    margin-bottom: 10px;
  }

  .popup-title {
    font-weight: bold;
    font-size: 18px;
    margin-bottom: 8px;
  }

  .popup-desc {
    font-size: 14px;
    color: #555;
    margin-bottom: 20px;
  }

  .popup-controls {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin: 10px 0;
  }

  .popup-dot {
    height: 10px;
    width: 10px;
    background-color: #ddd;
    border-radius: 50%;
    cursor: pointer;
    transition: background-color 0.2s;
  }

  .popup-dot.active {
    background-color: #f5a623;
  }

  .popup-nav {
    display: flex;
    justify-content: space-between;
    margin-top: 10px;
  }

  .popup-nav button {
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: #999;
    padding: 5px 10px;
    border-radius: 4px;
    transition: color 0.2s, background-color 0.2s;
  }

  .popup-nav button:hover {
    color: #666;
    background-color: #f0f0f0;
  }

  .popup-footer {
    text-align: center;
    margin-top: 20px;
  }

  .popup-footer button {
    background-color: #f5a623;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.2s;
  }

  .popup-footer button:hover {
    background-color: #e6951f;
  }
</style>

<!-- Overlay achtergrond -->
<div class="popup-overlay" id="popupOverlay" onclick="closePopup()"></div>

<!-- Popup container -->
<div class="popup-container" id="customPopup">
  <div class="popup-close" onclick="closePopup()">×</div>
  <div class="popup-header">What's new</div>

  <div class="popup-slide active">
    <img src="https://placehold.co/300x200?text=Geheel+vernieuwd" class="popup-image" alt="slide 1">
    <div class="popup-date">May 14, 2025</div>
    <div class="popup-title">App opnieuw opgebouwd</div>
    <div class="popup-desc">Now you can <a href="#">connect</a> your ClickUp data to Softr easily.</div>
  </div>

  <div class="popup-slide">
    <img src="https://placehold.co/300x200?text=Team+Dashboards" class="popup-image" alt="slide 2">
    <div class="popup-date">May 10, 2025</div>
    <div class="popup-title">VBF volledig vertaald naar Scans</div>
    <div class="popup-desc">Create powerful <a href="#">dashboards</a> for your teams in seconds.</div>
  </div>

  <div class="popup-slide">
    <img src="https://placehold.co/300x200?text=New+UI" class="popup-image" alt="slide 3">
    <div class="popup-date">May 5, 2025</div>
    <div class="popup-title">UI verbeteringen</div>
    <div class="popup-desc">A fresh coat of <a href="#">design</a> and smoother transitions are here.</div>
  </div>

  <div class="popup-controls">
    <div class="popup-dot active" onclick="showSlide(0)"></div>
    <div class="popup-dot" onclick="showSlide(1)"></div>
    <div class="popup-dot" onclick="showSlide(2)"></div>
  </div>

  <div class="popup-nav">
    <button onclick="changeSlide(-1)">←</button>
    <button onclick="changeSlide(1)">→</button>
  </div>

  <div class="popup-footer">
    <button onclick="window.location.href='#'">View all updates</button>
  </div>
</div>

<script>
  // 🔥 SESSIE CONTROLE - Hoofdfunctionaliteit
  const POPUP_SESSION_KEY = 'softr_news_popup_shown';
  
  const popup = document.getElementById('customPopup');
  const overlay = document.getElementById('popupOverlay');
  const slides = popup.querySelectorAll('.popup-slide');
  const dots = popup.querySelectorAll('.popup-dot');
  let currentSlide = 0;

  // Check of popup al getoond is deze sessie
  function shouldShowPopup() {
    return !sessionStorage.getItem(POPUP_SESSION_KEY);
  }

  // Markeer popup als getoond in deze sessie
  function markPopupAsShown() {
    sessionStorage.setItem(POPUP_SESSION_KEY, 'true');
    console.log('✅ Popup gemarkeerd als getoond voor deze sessie');
  }

  // Toon popup functie
  function showPopup() {
    popup.classList.add('show');
    overlay.classList.add('show');
    console.log('📢 News popup getoond');
  }

  // Sluit popup functie  
  function closePopup() {
    popup.classList.remove('show');
    overlay.classList.remove('show');
    markPopupAsShown();
    console.log('❌ Popup gesloten door gebruiker');
  }

  // Slide functionaliteit
  function showSlide(index) {
    slides.forEach((slide, i) => {
      slide.classList.toggle('active', i === index);
      dots[i].classList.toggle('active', i === index);
    });
    currentSlide = index;
  }

  function changeSlide(dir) {
    let newIndex = currentSlide + dir;
    if (newIndex < 0) newIndex = slides.length - 1;
    if (newIndex >= slides.length) newIndex = 0;
    showSlide(newIndex);
  }

  // Automatisch sluiten na 30 seconden (optioneel)
  function autoCloseAfterDelay() {
    setTimeout(() => {
      if (popup.classList.contains('show')) {
        closePopup();
        console.log('⏰ Popup automatisch gesloten na 30 seconden');
      }
    }, 30000); // 30 seconden
  }

  // 🚀 HOOFDINITIALIZATIE
  document.addEventListener('DOMContentLoaded', function () {
    console.log('🔄 Popup systeem geladen');
    
    // Softr specifieke aanpassing
    const parent = document.querySelector('.custom-code1');
    if (parent) {
      parent.style.display = 'contents';
      console.log('✅ Softr custom-code1 container aangepast');
    }

    // Check of popup getoond moet worden
    if (shouldShowPopup()) {
      console.log('🆕 Eerste bezoek deze sessie - popup wordt getoond');
      
      // Kleine vertraging voor betere UX
      setTimeout(() => {
        showPopup();
        autoCloseAfterDelay(); // Start auto-close timer
      }, 1000); // 1 seconde vertraging
      
    } else {
      console.log('✋ Popup al getoond deze sessie - wordt overgeslagen');
    }
  });

  // Keyboard ondersteuning (ESC om te sluiten)
  document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape' && popup.classList.contains('show')) {
      closePopup();
    }
  });

  // 🔧 DEBUG FUNCTIE (verwijder in productie)
  function resetPopupSession() {
    sessionStorage.removeItem(POPUP_SESSION_KEY);
    console.log('🔄 Popup sessie gereset - popup zal weer verschijnen');
  }

  // Maak reset functie beschikbaar in console voor testing
  window.resetPopupSession = resetPopupSession;
</script>

<!-- Softr compatibility observer -->
<script>
  const observer = new MutationObserver(() => {
    const codeBlock = document.getElementById('custom-code1');
    if (codeBlock) {
      codeBlock.style.display = 'contents';
      console.log('✅ display: contents toegepast op #custom-code1');
      observer.disconnect();
    }
  });

  observer.observe(document.body, { childList: true, subtree: true });
</script>

@jaspijk Thank you!