Generate a countdown timer Gutenberg block
Countdown timers convert. They also often cause Cumulative Layout Shift because the number digits change width at render, pushing the rest of the page around. Most third-party countdown blocks do not fix this.
A generated Gutenberg block can be built with monospace or fixed-width digit containers from the start, so the layout never shifts, and the expiry logic runs both server-side (for SEO-visible expiry text) and client-side (for live ticking).
Why generate it instead of installing an existing plugin?
Ultimate Blocks, Kadence, GenerateBlocks all include countdowns. They are fine. They also come bundled with their full block library. For a single countdown need you usually do not want all of that loaded.
A standalone countdown block registers one block and one tiny script. Timezones are handled correctly (the editor picks a timezone, visitors see the deadline regardless of their local time). When the countdown expires, the block swaps to an expiry message server-side, so SEO crawlers see the post-expiry state.
Small bonus: the block supports multiple formats (D/H/M/S, labels on/off, compact mode) via block attributes so editors do not need to touch CSS.
Example prompt
This is the kind of description that generates this plugin. You can start from it and tweak whatever you need before hitting generate.
Plugin name: Acme Countdown
Block acme/countdown with attributes:
- end_datetime (ISO 8601, required)
- timezone (IANA name, default "Europe/Madrid")
- format ("d-h-m-s", "h-m-s", "compact")
- show_labels (bool)
- expiry_message (string, rich text)
- cta_label, cta_url (optional, shown while active)
Save: return null (dynamic render).
PHP render_callback:
- If current time >= end_datetime (in timezone) -> render expiry_message.
- Else render digit containers with fixed widths and data-attribute with remaining seconds.
Frontend JS (1KB): reads data-remaining, ticks every 500ms, formats into the selected format. Uses requestAnimationFrame for smoothness. No layout shift — the digit containers are fixed width.
SEO: expiry state is rendered server-side, not only in JS.What the generated plugin typically includes
- Block with timezone-aware attributes
- Server-side render with expiry swap (SEO visible)
- Tiny JS tick with fixed-width digit containers (zero CLS)
- Optional CTA button during active countdown
- Editor preview that matches front-end styling
Formats, labels, and styles are block attributes you set per instance. If you need multi-language expiry messages, describe locales and the block picks by site language.
Frequently asked questions
What about DST transitions?
The countdown ends at the exact instant regardless of DST. The digit format adjusts automatically because we count from now to the fixed UTC instant.
Can it restart automatically for evergreen campaigns?
Yes. Describe evergreen mode in the prompt (e.g., "48h from first visit, per visitor"); the plugin stamps a cookie and the expiry becomes per-visitor.