A Badge Is Only as Good as Its Renewal Date: UK Trade Accreditations in Elementor Pro
There's a particular kind of awkward phone call where a client rings to say a customer has spotted a Gas Safe badge on their site and asked for the registration number. Because the badge has been sitting in a footer since a rebuild in 2019, nobody in the office knows the number, and the membership actually lapsed two renewals ago. That's not a design problem. It's a compliance problem, and it's one you can design out.
Most accreditation blocks on UK trade and professional-services sites are hand-placed images in a section. That works for about four months. After that the logos drift, the numbers never appear, and nothing on the page knows whether the certificate behind the badge is still live. Since these marks are claims about a business's competence, and the CMA takes a dim view of claims a trader can't substantiate, they deserve better plumbing than a PNG.
Start with a register, not a widget
Resist the urge to drop four images into a container and call it done. Build one source of truth first: a custom post type called something like accreditation, or a single repeater field on an options page if the client only has a handful. Every badge on the site then renders from that list — header, footer, service pages, the lot.
The reason is maintenance, not elegance. When the NICEIC renewal lands in March, someone edits one record and every instance updates. If the record is wrong, at least it's wrong in one place, which is a far better failure mode than six copies of an old logo across eight templates.
The fields that earn their keep
Thin registers rot. Give each record enough to be genuinely useful:
- Scheme name — Gas Safe Register, NICEIC, FCA, Checkatrade, TrustMark, CHAS, whichever applies.
- Membership or registration number — the thing customers actually ask for. Keep it as text, not a number field, because half of them contain letters.
- Expiry date — the whole point of this exercise.
- Last verified — the date you last checked the scheme's own register. Different from expiry, and often the more honest field.
- Verification URL — a deep link to the entry, not just the homepage.
- Logo — ideally SVG, with a sensible fallback.
- Scope line — optional, but useful where a membership covers one discipline and not another.
If you're using ACF, the date picker returns Ymd by default, which sorts correctly and compares cleanly. Leave it that way.
Wiring it into a Loop Grid
A Loop Grid with a Loop Item template is the least fussy way to render this in Elementor Pro. Inside the item, drop an image widget bound to the logo field, a heading bound to the scheme name, a text widget for the number, and a button or text link bound to the verification URL.
Two details worth getting right at the template level. First, set the image widget's alt text to a dynamic tag that combines the scheme name and the number, rather than leaving it to pull the raw attachment alt. Second, use a fixed height on the image (I usually cap at 88px on desktop, 64px on mobile) with object-fit: contain. Trade logos are wildly inconsistent — some are wide wordmarks, some are square crests — and without a height cap the row looks like a ransom note.
Order the loop by expiry date ascending if you like watching the clock, or by a manual order field if the client has opinions. They will have opinions.
The expiry problem, and a small fix
Elementor Pro's dynamic tags will happily print a date. They won't, on their own, decide whether the widget should exist. If you want a badge to disappear the day a certificate lapses, you have three honest routes: a conditional-display add-on, a query filter on the loop, or a shortcode.
The shortcode is the least dependency-heavy option and it survives plugin churn:
add_shortcode( 'accreditation', function () {
$expiry = get_field( 'expiry_date', get_the_ID() );
if ( ! $expiry ) {
return '';
}
$today = strtotime( current_time( 'Y-m-d' ) );
$expires = strtotime( $expiry );
if ( $expires < $today ) {
return '';
}
$soon = $expires < strtotime( '+45 days', $today );
$note = $soon ? '<span class="accr-due">Renewal in progress</span>' : '';
return '<div class="accr-live">' . $note . '</div>';
});
Wrap the badge markup in that condition and you get two behaviours for free: lapsed credentials vanish, and anything inside its renewal window shows a small, calm note. That note matters. A badge that disappears with no explanation reads as a website glitch; a badge that says renewal is in hand reads as a business that has its act together.
Logos that survive a screen reader
An accreditation logo is an image conveying information, not decoration. So the alt text should be Gas Safe Register logo, registered business 512345, not gas-safe-logo and not an empty alt. If you're inlining SVGs, give them a <title> element and role="img".
Also: never communicate status through colour alone. If a badge turns amber when it's close to expiry, add the word. And check the registration number text against the background — grey-on-light-grey is a classic own goal on trade sites, and it's exactly the detail a less-confident visitor needs to be able to read.
The verification link
Put the link on the registration number, not the logo. It's a clearer affordance, and it avoids the odd situation where clicking a scheme's trademark image takes people off-site. Use target="_blank" with rel="noopener", and write the link text as an instruction — Verify this registration on the Gas Safe Register — rather than click here. Screen reader users navigating by link list will thank you.
One caveat for FCA-authorised firms: point the link at the Financial Services Register entry, not the firm's own About page. The whole value of the badge is that a third party vouches for it.
Stacking on a 360px screen
Four logos across a phone screen is a squash. Let the grid do the work: two columns from 480px down, one column below about 380px, and set the gap generously so the badges don't touch. If you're on a Loop Grid, that's the Columns control at each breakpoint. If you're hand-rolling, repeat(auto-fit, minmax(140px, 1fr)) gets you most of the way there.
Test on an actual phone with the actual logos, not with placeholders. Wordmarks that look balanced in Figma can wrap their own registration numbers onto two lines at 360px.
The renewal workflow nobody asks for
This is the part that stops the phone call happening. Three small habits, none of them glamorous:
- An admin column. Show the expiry date in the accreditation list table so the client sees it every time they log in. No colour coding needed; the date speaks for itself.
- A weekly nudge. A short WP-Cron job that emails you and the client's nominated contact with anything expiring in the next 45 days.
wp_mail()and aWP_Queryon the meta key is genuinely all it takes. - A quarterly register check. Diaries beat databases here. Registers change independently of expiry dates — a firm can be removed mid-term — and a badge on a site won't know. Fifteen minutes on the relevant register four times a year is cheaper than a complaint.
Then add the renewal update to the client's care plan as a line item with a price or a scope note. It's work. Charge for it, or at least name it.
Before you hand the site over
Run this list once, then put it in the handover document:
- Every badge on the page is in the register, and there are no leftovers in old templates or the footer from the previous build.
- Each logo has meaningful alt text including the number.
- Each number links to the correct entry on the scheme's own register.
- Expiry dates are populated and the conditional logic is tested by temporarily setting one date in the past on staging.
- The client has been told, in writing, that they need to notify you when a membership lapses or is not renewed.
That last point is the one people skip. It's also the one that turns a badge block from a nice touch into something you can stand behind in 2026 and beyond.