Creating a floating “Newsletter” button as a WordPress mu-plugin is a smart way to boost subscriptions without disrupting your site’s layout.
Unlike standard plugins, a must-use (mu) plugin loads automatically on every page, ensuring consistent functionality while staying lightweight and efficient. In this guide, we’ll explore how to build a multi-language floating button that adapts to your site’s active language, giving visitors a seamless experience whether they browse in English, Italian, Thai, or any other supported language. The result is a clean, professional, and accessible subscription entry point that feels integrated rather than intrusive.
Table of Contents
What you’ll build
A tiny, theme-agnostic must-use (MU) plugin that adds a small floating pill labeled Newsletter on English pages and จดหมายข่าว on Thai pages (for you can be any other language you need). On click, it opens your external, multilingual subscribe page in a new tab. The button:
-
stays bottom-right on mobile (thumb-reachable)
-
moves to top-right on desktop (optional, adjustable)
-
changes hover color from yellow to
#1f63ac -
never turns purple after visit
-
auto-labels EN/TH (Polylang/WPML/site locale)
Why a floating “Newsletter” button mu-plugin
-
Always on: it can’t be deactivated accidentally when switching themes.
-
Zero theme edits: survives theme updates.
-
Lightweight: one file, no dependencies.
Prerequisites
-
WordPress admin access (file manager or SFTP).
-
Your hosted subscribe URL from your ESP (e.g., Mailchimp/Brevo/MailPoet page).
Step 1 — create the mu-plugins folder
If it doesn’t already exist, create it at: wp-content/mu-plugins
Step 2 — add the plugin file
Create a file named newsletter-fab-link-label.php inside wp-content/mu-plugins/ and paste the code below.
<?php /** * Must-Use Plugin: Newsletter FAB (Link + Small Label, EN/TH) * Description: Small floating "Newsletter" pill that opens your multilingual subscribe page in a new tab. Auto EN/TH label, hover color swap, mobile/desktop positioning. * Author: You * Version: 1.3.0 */ /* Front-end only */ if ( is_admin() ) { return; } add_action('wp_footer', function () { /* 1) Your hosted subscribe page (already multilingual) */ $subscribe_url = 'https://example.com/your-subscribe-page'; // <- replace /* 2) Detect current language: Polylang > WPML > site locale */ $lang = function_exists('pll_current_language') ? pll_current_language('slug') : (defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : substr(get_locale(), 0, 2)); /* 3) Button label per language */ $labels = [ 'en' => 'Newsletter', 'th' => 'จดหมายข่าว', // or 'สมัครรับข่าวสาร' if you prefer a more action-driven verb ]; $label = isset($labels[$lang]) ? $labels[$lang] : $labels['en']; /* 4) Optional: hide on specific pages (e.g., checkout/cart). Add slugs/titles/IDs as you like. */ if ( is_page( array('checkout','cart') ) ) { return; } ?> <style> :root{ /* Size & shape */ --fab-font-size: 13px; --fab-padding-y: 7px; --fab-padding-x: 12px; --fab-radius: 999px; /* Colors */ --fab-bg: #ffd400; /* idle (yellow) */ --fab-bg-hover: #1f63ac; /* hover (blue) */ --fab-fg: #111; /* idle text */ --fab-fg-hover: #fff; /* hover text */ /* Effects & positioning */ --fab-shadow: 0 10px 25px rgba(0,0,0,.18); --fab-right: max(14px, env(safe-area-inset-right)); --fab-bottom: max(14px, env(safe-area-inset-bottom)); --fab-top: max(14px, env(safe-area-inset-top)); } /* Base appearance */ a.newsletter-fab{ position: fixed; z-index: 9998; display: inline-flex; align-items: center; justify-content: center; padding: var(--fab-padding-y) var(--fab-padding-x); background: var(--fab-bg); color: var(--fab-fg); font-size: var(--fab-font-size); font-weight: 700; line-height: 1; border-radius: var(--fab-radius); text-decoration: none; box-shadow: var(--fab-shadow); transition: background-color .15s ease, color .15s ease, transform .06s ease; -webkit-tap-highlight-color: transparent; } a.newsletter-fab:hover, a.newsletter-fab:focus-visible{ background: var(--fab-bg-hover); color: var(--fab-fg-hover); outline: none; } a.newsletter-fab:active{ transform: translateY(1px); } /* Avoid purple visited state */ a.newsletter-fab, a.newsletter-fab:link, a.newsletter-fab:visited{ color: var(--fab-fg); text-decoration: none; } #newsletter-fab:visited{ color: var(--fab-fg) !important; } /* Positioning: mobile first = bottom-right */ a.newsletter-fab{ right: var(--fab-right); bottom: var(--fab-bottom); top: auto; } /* Desktop/tablet: switch to top-right */ @media (min-width: 992px){ a.newsletter-fab{ bottom: auto; top: var(--fab-top); } /* Admin bar safety on desktop (toolbar ~32px) */ .admin-bar a.newsletter-fab{ top: calc(var(--fab-top) + 32px); } } </style> <a id="newsletter-fab" class="newsletter-fab" href="<?php echo esc_url($subscribe_url); ?>" target="_blank" rel="noopener noreferrer" aria-label="<?php echo esc_attr($label); ?>" ><?php echo esc_html($label); ?></a> <script> // Optional GA4 event tracking // document.getElementById('newsletter-fab')?.addEventListener('click', ()=>{ // window.dataLayer = window.dataLayer || []; // window.dataLayer.push({event:'newsletter_button_click', lang:'<?php echo esc_js($lang); ?>'}); // }); </script> <?php });
Save the file, clear caches, and reload your site.
Editorial Plan Prompt Generator for ChatGPT
Build Your Own Chrome Extension: Editorial Plan Prompt Generator (Privacy-First, No Subscriptions)
Step 3 — customize quickly
-
Subscribe page URL: replace
https://example.com/your-subscribe-pagewith your ESP’s hosted form URL. -
Colors: change
--fab-bg,--fab-bg-hover,--fab-fg,--fab-fg-hover. -
Size: tweak
--fab-font-sizeand paddings. -
Position: nudge with
--fab-right,--fab-bottom,--fab-top. For “a little lower” at top-right, increase--fab-top(e.g.,--fab-top: 40px;). -
Language labels: edit the
$labelsarray (e.g., switch Thai toสมัครรับข่าวสาร). -
Hide on pages: add more slugs/IDs to the
is_page()array.
Step 4 — common variants
Icon-only (super unobtrusive)
Replace the anchor’s inner text with an SVG envelope and keep the aria-label for accessibility.
<a id="newsletter-fab" class="newsletter-fab" href="..." target="_blank" rel="noopener" aria-label="Newsletter"> <svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true"> <path d="M2 6.5A2.5 2.5 0 0 1 4.5 4h15A2.5 2.5 0 0 1 22 6.5v11A2.5 2.5 0 0 1 19.5 20h-15A2.5 2.5 0 0 1 2 17.5v-11Zm2.1-.5 7.4 5.3L19 6h-14.9Zm-.6 1.2v10.3c0 .39.31.7.7.7H19.5c.39 0 .7-.31.7-.7V7.2l-8.2 5.9a1.5 1.5 0 0 1-1.76 0L3.5 7.2Z"/> </svg> </a>
Optionally shrink padding for a round button and set a fixed width/height.
Modal (iframe) with graceful fallback
Some ESPs block iframes (X-Frame-Options). If yours allows it, open a modal with an <iframe>. If not, show a fallback link. Keep your current link-only version for maximum compatibility.
Step 5 — analytics (ga4)
Uncomment the dataLayer.push snippet in the plugin to track clicks. Create a GA4 event named newsletter_button_click and build a small funnel.
Step 6 — accessibility and ux details
-
The button uses an aria-label and a visible text label.
-
Tap highlight removed on iOS for a cleaner feel.
-
Focus states use the hover color; you can add a visible outline if your brand requires stricter accessibility.
Troubleshooting
Floating “Newsletter” button: It stays at the top on mobile
Explicitly unset top for mobile and move it to desktop only.
a.newsletter-fab{ bottom: var(--fab-bottom); top: auto; } @media (min-width: 992px){ a.newsletter-fab{ bottom: auto; top: var(--fab-top); } }
Floating “Newsletter” button: The visited link turns purple
Already overridden in the CSS. If a theme rule still wins, add:
#newsletter-fab:visited { color: var(--fab-fg) !important; }
Floating “Newsletter” button: Overlapping cookie/chat widgets
Increase bottom offset on mobile or top offset on desktop:
:root{ --fab-bottom: 72px; } /* if a cookie bar sits at the bottom */
Floating “Newsletter” button not showing up at all
-
Ensure the file is in
wp-content/mu-plugins/. -
Confirm no fatal errors (check Site Health > Info > Debug).
-
Clear page cache/Cloudflare and hard-refresh.
Quick reference (tweak table)
| What to change | Where | Example |
|---|---|---|
| Subscribe URL | $subscribe_url |
https://your-esp.com/subscribe |
| EN/TH label | $labels array |
'th' => 'สมัครรับข่าวสาร' |
| Idle color | --fab-bg |
#ffd400 |
| Hover color | --fab-bg-hover |
#1f63ac |
| Text color | --fab-fg |
#111 |
| Hover text | --fab-fg-hover |
#fff |
| Size | --fab-font-size, paddings |
13px, 7px/12px |
| Mobile position | --fab-bottom, --fab-right |
16px |
| Desktop position | --fab-top, --fab-right |
32–64px |
| Hide on pages | is_page() |
array('checkout','cart') |
Floating “Newsletter” button: Closing tips
-
Keep the button label short and unambiguous (Newsletter / จดหมายข่าว).
-
Test both languages on real phones.
-
If you later switch ESPs, you only change one URL in the MU file.
Digital Designer, blog writer and also a tech enthusiast.
He loves to write content for blogs, podcasts, design websites, logos, brochures, banners and anything that sends a message to an audience.
You can contact Daniele at the link below:



