• Skip to main content
  • Skip to footer
Equalize Digital Home

Equalize Digital

Website Accessibility Consulting, Training, and Development

  • My Account
  • Swag Shop
  • Checkout
  • Services
    • Accessibility Audits
    • User Testing
    • Accessibility Remediation
    • VPAT & ACR Preparation
    • Accessibility Monitoring
    • Web Accessibility Training
    • Accessibility for Agencies
  • Accessibility Checker
    • Overview
    • Features
    • Pricing
    • Documentation
    • Support
    • Buy Now
  • Company
    • About Us
    • Our Team
    • Industry Expertise
    • Accessibility Statement
    • Contact Sales
    • Become An Affiliate
  • Learn
    • Online Courses
    • Accessibility Meetup
    • Articles & Resources
    • Accessibility Craft Podcast
    • Upcoming Events
    • Office Hours
    • Custom Accessibility Training
    • Global Accessibility Awareness Day
  • Contact Sales
  • My Account
  • Checkout
Home / Learning Center / Changelog 001: Language, Landmarks, and Links

Changelog 001: Language, Landmarks, and Links

Article PublishedJuly 16, 2025Last UpdatedJuly 16, 2025 Written byEqualize Digital

Accessibility Checker Changelog live with Steve Jones and William Patton.

The first episode of the Accessibility Checker Changelog livestream aired recently, hosted by CTO Steve Jones and lead developer William Patton. This new biweekly series offers a behind-the-scenes look at what’s new in the Accessibility Checker plugin, development decisions, and the broader WordPress accessibility landscape.

This episode focused on Languages, Landmarks, and Links, along with several under-the-hood improvements and a look ahead at what’s coming next.

Watch the Video

Video Transcript

Show/Hide Transcript

Steve: [00:00:00] And we are live. Let’s see,

so this is a first time stream for us. Let’s see if we can get a confirmation if this is working.

William: Yep. Yep. I see on YouTube now.

Steve: Oh, looks like it’s working to, I got confirmation that we’re going out to YouTube.

So if anybody is watching, feel free to post in the chat and let us know you’re there. Know that, let, give us a thumbs up if everything’s working. Let’s see if we’re going out to X.

And it looks like we are going out to X. Let me let me repost [00:01:00] this. Cool. Alright, so this is episode one of what we’re calling the Accessibility Checker Changelog where we will be talking through what’s new in the Accessibility Checker. I’m just gonna give it a little bit of time to let people join and make sure that the streams are up and working.

Let’s see. Looks like, okay. Looks, we’ve got confirmation from Amber that things are working. Awesome. Cool. If you’re joining in, feel free to ask a question anytime. This is gonna be a free flowing live stream where we can field questions as they come in and so feel free to chime in.

Just wanna say welcome to the Accessibility Checker Changelog. So I’m here with I’m Steve [00:02:00] Jones. I’m CTO of Equalize Digital and I’m here with with William. William, would you like to introduce yourself?

William: Yeah, I’m Will. I write the code that Steve asked me to, I mostly break things. We will see how long it takes for me to break something on this stream.

Oh my, I may have just broken something already.

Steve: It’s alright. It’s okay to break things as, as long as you know how to fix ’em. We’re here talking about the Accessibility Checker. Some of you may know, what the Accessibility Checker plugin is, and some may not, but for those that don’t, the Accessibility Checker is an automated accessibility scanning plugin to help your WordPress become

and stay accessible. The Accessibility Checker is a suite of plugins at this point. We have the Accessibility Checker free plugin, which you can get from our website at Equalize Digital dot com slash Accessibility dash Checker. We have a premium plugin, which we call Accessibility Checker Pro, which adds in many [00:03:00] premium features like such as full site scanning.

And then we have a few add-on plugins that you get at different levels of the premium plugin. We have an audit history plugin, which, which will track your issues over time and allow you to export that to CSV files. We have a multi-site add-on which will allow you to manage all of your subsites the licensing for all of your subsites in one place at the network level, as well as many other settings.

And we have an export add-on, which allows you to export a lot of the data that the Accessibility Checker creates into CSV files. Welcome to the first episode. What we’re aiming for, William and I are aiming for is a casual user and developer focused conversation around accessibility and around the Accessibility Checker and around being WordPress product creators.

This first episode we’re calling. [00:04:00] We’re calling languages, landmarks, and links.

So we’ll cover what’s new in the plugin as far, and we’ll take a look under the hood and we’ll do some demoing and we’re preview what’s coming next for the Accessibility Checker. So first up, languages. So in, in a recent release of the plugin, not the latest, but I think two, two versions back, we released translations for the plugin.

We are now translating the plugin into 32 languages. I and this kind of came out of our trip to WordCamp EU. And, and this kind of sprung from us being an accessibility plugin and the importance of accessibility, which is including everybody and making the web accessible to everybody.

And that actually extends out [00:05:00] into translations as well. If you like to get a deep dive on translations. Let me pull up a screen here. If you’d like to get a deep dive and into why and a little bit of how we implemented translations in the plugins, I would point you over to our latest episode of Accessibility Craft, where you can hear Chris and Amber and I talk through that a bit while we drink, Not Beer.

It’s not beer. So give that a listen. So let’s jump in. Languages, William.

Translations

William: Yes.

Steve: So we implemented we were tasked with at kind of a, at the spur of the moment, which doesn’t always fall into our dev workflow with these translations. And we set out to maybe spend a couple days translating the plugin and we actually ended up spending, you know, two or three weeks on it.

William: Couple of days, very quickly became a couple of weeks, [00:06:00] couple of days we had all the translations available. It turns out that it is quite difficult to integrate translations into WordPress plugins, or it’s more difficult than it should be to keep updated.

Steve: Right, right. And and why is it important to.

From a development standpoint, to have these systems where it’s updated, can’t, you, can’t, you just translate ’em and you’re good to go.

William: You can

just translate it and you’re good to go if you don’t wanna make any changes to your plugin ever again. I’ve learned that it is very easy to just wanna tweak a line of code that includes a string you might want to update, some help text.

Almost every single release there is a minor reword of some string that benefits users immensely, but it’s a real pain in the neck for keeping the translations [00:07:00] updated. Particularly when you’re relying on other users doing the translations. If you are looking to the community to do your translations, every single time you make a string change, you have to wait on someone.

You know, doing the translation, you have to wait on a PTE manager going through approving the translations. It’s not a fast process.

Steve: Right. Right. And you really don’t want to create barriers for your dev team where they feel like they don’t want to change the string because they know then it’s gonna cause an issue for Yes.

Yeah. So we built a kind of a continuous integration, a workflow that kind of allows our development process to automatically translate these strings. So the WordPress dot org has GlotPress, which allows you to utilize you know, people contributing strings, translated [00:08:00] strings to your plugin.

But, you know, as I stated, we have our free plugin, which is hosted on WordPress dot org and has the benefit of GlotPress. But we have four other plugins that are premium plugins that are, don’t have that ability. So how do you translate to 32 languages when you don’t speak 32 languages?

William: Yeah, you just make up as you go. Really Realistically, there is services out there that can perform these translations. The service that we have picked is AI backed, which, you know, the quality of the translations is potentially questionable, but having no translations is, you know, horrible for all these users that don’t speak English.

Yeah. So this is the tool here, PTC.

Steve: Yep.

William: It comes from WPML, I believe.

Who? Yeah, they provide AI [00:09:00] backed translations apparently better than humans. Yeah. That, you know, I question that’s their claim.

Steve: Yeah. That’s a bold claim, right? Better than human translations. And yeah, so I don’t think it, we didn’t think it was, would be wise to just translate it with an AI translation without any validation.

So at WordCamp EU, you know, a Amber Hinds, our CEO kind of shopped it around a little bit. We had a little bit of a pre-release put together of the plugin that she demoed for a few people to get some feedback. And the feedback seemed to be fairly positive and that it, that they were able to read the translations.

There didn’t seem to be anything funny or weird or, you know, and sometimes even with translations, things could be inappropriate. Right. So the question is, do you. Is that good enough that you’ve done a little bit of validation and as the plugin moves on you’re [00:10:00] validated more and more, right?

With more people using it. And if anybody brings up an issue with it, the, we do have a glossary where we can actually modify these strings and stuff out, even outside the plugin. So when the translations are generated that it, you know, it pulls the correct string. So we wanted to provide these translations, and AI gets us very far in that to where even months ago or a year ago, we couldn’t do anything close to this.

And a hard thing with you know, the WordPress dot org hosted plugins is that, you know, these are volunteer based translations and you’ve gotta, you’ve gotta get, you’ve gotta get people to contribute their time to translate those. And our free plugin had been translated into a handful of languages most notably German.

We had the most coverage in that. But what this does, this is allows us to have a unified system of translating. And [00:11:00] something that we’re not dependent on on contributors giving their time, which, you know, a lot of people have limited time these days and our plugin is quite large and has thousands of strings that need to be translated.

So we will keep, we’ll continue to test this and we will continue to get feedback on these translations moving forward. Let’s see. We have some comments here. Let’s see. Da Dave. AI translation’s better than humans possibly. Yeah. I think you can bring this up on the screen. Screen. Let’s see. So this is my first time running a restream, but yeah, there we go.

Possibly. Yeah. I think it so far we’ve had a lot of success with this service and they actually had a 30 day free trial, and that was enough time for us to work out our dev workflow, get it into the plugin, do some testing, and then by the time we were ready to go live with it, they, it’s like a flat $30 a month, you’re not paying tokens.

And so far so good on that [00:12:00] service. We may talk a little bit more about the technical stuff on this, on our technical deep dive, but so that’s the languages.

Landmarks

Steve: And next let’s talk about landmarks. So we have a new feature called Landmarks which we’ve had

William: A new feature.

Steve: We invented it

William: for the HTML spec.

Steve: Yep. So for those from scratch, for those out there landmarks are you know, semantic HTML tags and they’re part of the acce, you know, the accessibility tree. And it helps screen readers identify, you know, where in the page the users are and they’re important in the plugin so that we can identify where issues are and that we can then at some point filter out issues to people with certain user roles.

Since we’re talking about it, maybe I should just demo it now, William. Let’s see. Yeah. What we’ve done with landmarks is we’ve, so when you scan the [00:13:00] page in the database, it’ll actually store the landmark parent in which it’s found in, and also for the technical folks out there, a selector to help us identify where it is on the page.

So now inside of the editor, so I’ve scanned this page, and now then in the Accessibility Checker meta box here, I can expand out the details tab for each issue. And you can see we now have a landmark column and we’ve integrated this landmark with our front end highlighter. So if I click that, it’ll open up the front end page, scrole down to the issue and highlight it with a you know, the pink dashed line.

And we also have a label here where it says landmark complimentary, which is like an aside. And it highlights it so you can see where it’s at, and then you can still run your front end highlighter to highlight issues and move on like you normally would. [00:14:00] So this is our first step into creating more features inside the pro plugin, where say you’re, say you have a user that’s like an editor role, right?

And editor role editors can’t really ac access the you can’t really access the global elements on the page. So you want to you probably wanna filter those issues out and only show them issues that pertain to what’s inside the content. I can show a couple more while we’re at it.

So like this nav item, right? So if I was an. If I was editing this post as a content editor, then I likely cannot edit this nav here, which is, it’s a navigation for the next and previous posts. So that issue is noise to me ’cause I can’t really do anything about it. This is more like a, an admin role or like a develop a developer would have access to.

So that is landmarks and there’s more to come in the [00:15:00] pro plugin as far as filtering out based on user rule and adding this into our open issues and into our ignore log as well. You got any follow ups on landmarks? William?

William: No, I didn’t. I didn’t really touch this feature yet, but I’m looking forward to creating the ability to handle the filtering so that only editors are gonna be able to access issues

they can correct right themselves, which we, you know, a big usability enhancement for a lot of websites that aren’t just one person running all the things. And that, you know, most websites these days are more than one person, right? You’ve got the overall, like owner of a website that might wanna see all the issues, but if you have a content creator, they’re only going to wanna see a small subset that they can tackle.

Links

Steve: Yeah. Yeah. [00:16:00] Cool. So finally we have links. We’ve made updates to our link improper rule, which the actual readable title of that rule is improper use of link. And where it was, what was the issue there? William, can you describe why we had to add this?

William: Yeah. So on. I can’t remember the exact system, but we discovered on one of the websites that we were auditing, they had tabs that were built with markup that maybe isn’t ideal.

They were using links with role of reassignments as opposed to just, you know, containers that are, or buttons that are, you know, a role of tab. So yeah, items with links with, what do you call that? The hashtag, right? Yeah. Hashtag, yep. It’s like an improper link. But with the role of tab actually [00:17:00] technically is valid semantics because the role has changed.

Yeah. So markup just like this? Yeah. Once the role is assigned, this is no longer a link as such and should be treated as the role of tab as opposed to as the role of link.

Steve: So in previous versions of the plugin, this would actually flag as an improper use of link, correct?

William: Yes.

Steve: So now I’ll just say this so we can actually see it in action.

To describe what’s on the screen here, what I’m looking at is I’m in a, I’m in a WordPress post in the edit screen and I just have a HTML block with some markup in it. And it’s an a href with a role equals tab. And the link just has a title of link with role of tab. So I scan the page again.

And it’s not being flagged. There is another one an improper link on the pa learn more link on the page. But [00:18:00] that’s a separate issue. So if I remove the role equals tab from the markup here, and then I re-save the page we will see that issue. So now in the details tab of the Accessibility Checker meta box, you can see that the the markup that we had is now showing as an improper link.

It’s because we’re using the hashtag on it. But what this fix does is this actually allows anchor links that are being used as tabs to not flag as an issue in Accessibility Checker.

So that is

an update to that rule. And then as far as links, let’s see. So we’ve done some minor updates to the plugin, and it’s, the plugin’s been around for nearly five years, and it’s [00:19:00] amazing that we haven’t added some of these things before. So let me we added some links to the let me, I’ll have to, let me pull the screen up here.

So we’ve added some kind of quick links and making the plugin more, more accessible on the page. So we now have a an admin toolbar link, which, you know, gives you a quick link over to settings and a quick link over to fixes. And this is available on the back end and the front end, which just allows you to jump to these quicker.

And this is our, just our first iteration of using this. And this will, we will have more information in here. We plan to add notifications of new features or notifications of maybe accessible issues throughout the page. And then on the, in the WordPress admin on the plugins page, we’ve added some kind of quick links to our documentation, to our support to rate the plugin [00:20:00] and and we’ve added, yeah, I think that’s it, right, William?

Yeah. Those are some quick links. Yeah. And what we’re trying to do is we’re just trying to sprawl the Accessibility Checker out into the WordPress admin to make things easier for you. Actually, I’m wrong. We added this settings link as well next to the plugin. So a quick link over to settings, and I love these when plugins have a settings link.

’cause I, you know, you inevitably install a plugin, you activate it, and then you’re like, okay, where is this settings? Is it in a, is it under tools, is it under settings? Is it in the parent? And I’d rather just have a link here, just a quick link over to the settings. So we’re doing these small things to try to make the plugin more usable.

So that is, let me switch back to us that are, that’s the recent released features. We’ve demoed a couple of them.

Translations Demo

Steve: We wanna demo [00:21:00] translations since we haven’t done that yet. Let me William and I got pretty good at reading French through our testing. So let me go to settings and then switch the language over to French and hit save.

So first off, you’ll notice that Accessibility Checker doesn’t get translated and we were a little verbose in our translation, adding translation functions to our strings throughout the plugin, and we did translate some of our branded names. Fortunately in PTC there’s a glossary where you can define strings not to translate or what to translate those to.

So now when our. Translation files get created. Then Accessibility Checker stays, Accessibility Checker. And the same with Accessibility Checker Pro. And you can see here that I clicked on the Accessibility Checker [00:22:00] welcome page, which you know, has our stats and a lot of our links and to documentation and stuff.

And most things are all translated into French. And

yeah. So a big thing that we ran into, and maybe William you would wanna speak to this a little bit, was the difference between translating PHP and translating JavaScript, right?

William: Yes. So translating PHP is a pretty straightforward process. There’s lots of documentation, articles. It works the same way.

It has always worked. Translations inside JavaScript, though. Not so much. So the JavaScript translations for WordPress uses an alternative translation mechanism. Jed, I believe it’s called, or JED. It is not the same as “Get” text. It works very similarly, but the output differs. So when it comes to translating JavaScript strings, there is a couple of [00:23:00] gotchas, so to speak.

So first off, the translation system is different in WordPress that it’s shared, which means it uses different files. It doesn’t read directly from the PO or the MO files actually requires JSON files. And those JSON files need to be, or ideally, or individualized for every single bundle that you have. So every JavaScript file that you include on the page, ideally has its own JSON file and even.

Detecting strings inside the JavaScript files is a bit iffy because, you know, we all build our JavaScript, but most systems these days have built in place that Minify amplify, compress all of your JavaScript. And a lot of these systems change the function names, which means underscore, underscore functions, the translation functions that you expect might be renamed.

So [00:24:00] by the time you actually run your, you know, your scan across all of your code base to find all the strings, potentially that function then that it’s looking for might not actually exist anymore. So we actually had to make modifications to our web pack configuration file to ensure that they get preserved so that when.

We use W-P-C-L-I to scan or plugin to detect the translations and build the pot file so that those functions remain to be found. Yeah, it’s that all of this is just phase one generation of a pot file is phase one of getting translations. Once you have that pot file, you have to translate it, which, you know, we use the external service.

The external service gives you back PO and MO files. And from those MO files, you then need to generate your JSON strengths. So it is a three step process to translate [00:25:00] JavaScript as opposed to just one and done the way that it is in PHB.

Steve: Yeah, and what I’m showing on the screen now is the code base and these different types of files like a PO file and the MO file and the JSON.

Files are what I’m showing here on the screen. These all live inside the languages folder. And a technical thing is these, we don’t package all these into the final build. We pull out the dot po file and only package the machine file, which is the.mo and the JSON files to keep the package size smaller.

William: So actually do wanna say that isn’t actually true for the free plugin that we push the.org because GlotPress relies on the MO and the PO files.

Steve: Right?

William: But for the profiles to save, you know, you having enlarged download sizes, we don’t include them as part of that bundle. [00:26:00]

Steve: Yeah. That’s a great point too.

And like with GlotPress so what happens now? We have our own languages file inside of inside of our plugin, even our free plugin and. But there’s also GlotPress is this a conflict? How do those two work together if German is translated by GlotPress? And then we have Germans translated by WPML which one takes priority.

William: So in most cases is gonna prioritize the languages that we have bundled in the plugin. And or ideally we would like that to be the case because we have all of the strings translated. However, what I discovered is that if WordPress has a bundle distributed for a specific language, then dependent on some system configuration, maybe WordPress will prefer the less translate option.

So if we have German translate it, [00:27:00] you know, might be 85%. WordPress is gonna consider that as close enough to full. To deliver it as its own bundle. And WordPress will, by and large prefer WordPress deliver translations over bundled. And you, there’s some filters and some workarounds you can do to prevent that happening, but is very much non-standard.

The standard behavior this WordPress will prefer its own provided translations.

Steve: Yeah. So as plugin creators, we have to make a decision, right? Like we have to, I if say we have German on GlotPress and it’s translated at 70%, but our AI translations are a hundred percent or 99%, right? We would, it could even be a worse case scenario than that.

What if the German has only translated 20%? Right. And. We actually wanted to [00:28:00] prefer what we have because we’ve actually had, we actually have the translations. We could use that filter, right? We could decide to then yes,

override core behavior. And you have to make a, you have to make a choice on whether or not you want to do that.

If you have a lot of activity on GlotPress around people contributing to translating those strings, and you have assurance that you will get pretty good coverage, then may, maybe you allow, you know, WordPress to choose it give priority to itself over what you have in the languages file.

Adding a Primary Key in the Database

Steve: So yeah, that’s a little bit of the technical background on the translations and, so we did add, this is not ne necessarily a feature, so with every release we have, we try to put some features in, but we actually inevitably do a lot of fixing which comes from, you know, just internal you know, bug fines and from our support and things like that. So a little [00:29:00] bit on the technical deep dive side here, William.

This was a very interesting issue that came up with the latest release was we ran into an issue with swapping from unique to a primary key in our custom WordPress database. So the Accessibility Checker has a custom database table and and we had a support client come in that was unable to.

Get the database to generate. William, can you speak to that a little bit?

William: Yeah, so the customer support request came in their database provider, so they’re using digital managed my SQL databases, which enforce primary keys on every single table using an SQL flag or MySQL flag, which, you know, a setting that was added in, I believe my SQL eight to force all tables to have primary keys.

So what we did have in our system was a unique key, which internally [00:30:00] MySQL will generate indexes is bit backed by it because it knows that will be a unique key. But a unique key is not the same as the primary key. It is treated the same by us as you know, the developers of this plugin. But MySQL gives priority to actual primary keys of our unique keys.

In almost all regards. So for MySQL to be the most efficient it can be, all tables should ideally have at least one primary key. I guess, so this user came in with the customer support saying that they were unable to actually activate the plugin, use the plugin because we did not have a primary key defined for our main database table storage.

And the solution is to define that unique key as the primary key. It’s, you know, an i ideal field. It is both unique and actual primary key. So yeah, we made that [00:31:00] swap it. It is non-user facing. I don’t, in some simple benchmarking I did, it doesn’t really seem to make MySQL measurably quicker. But at scale you know, huge scales this.

Absolutely will be faster query because this is a primary key rather than just unique.

Steve: Yeah. And this, and it’s quite interesting too because, you know, the kind of the age of the Accessibility Checker, right? Being you know, being almost five years old and it this not being a primary key the whole time.

And I think we know who’s to blame for that. Probably the guy that wrote the the code that generates,

William: We can go back and look at who wrote that.

Steve: I dunno. Yeah we won’t pull up the blame on that. But it’s worked, right? And this has never come up. And it, and this is the interesting thing about plug plugin development and is that, you know, as your plugin grows and it gets put on all kinds of [00:32:00] systems and as the systems that it’s running on.

Or actually maturing themselves, right? Like the things that come up, and this is less of a performance thing I think in the, in this regard, but it’s more of a Yes. A of a, an a technology advancing, right?

William: Yes. So by, as a general rule of thumb, all database tables should have something that’s unique about them, right?

And that is generally the primary key. We had defined the key that is now primary just as unique, which was effectively the same for our purposes. But at the scale of a managed database host like Digital Ocean, right? They might have one server with 500 or a thousand databases on it. It’s very important for them that all of their indexing as efficient as it can be.

And you know, at scale this was a requirement, but at individual site level, the difference is negligible. [00:33:00] But it’s better for us to support the bigger enterprise use case and the individuals site than it is to only support the individuals site.

Allowing the Front End Highlighter to Scan Pages

Steve: Right? Right. Cool. So one feature that another kind of little fix that we did in the latest release was around our front end highlighter.

And and a few versions back, we went through a major refactor where all of our rules were brought under the umbrella of axe-core and utilizing JavaScript for all of our. Page scans. And we had previously used PHP, the plugin started out using only PHP to parse the page and to evaluate for accessibility issues.

But where that gets troublesome is that you’re not really evaluating the rendered page. So over the years, we’ve been transitioning over to using JavaScript so that we can utilize a rendered page to [00:34:00] evaluate. And we finally I think it was three or four versions back we took a deep dive and we translated all the rules over to JavaScript.

And this kind of caused a little bit of issue for our frontend highlighter. So if you go to a page that doesn’t have any issues, the frontend highlighter, before we’d kick off a scan and it would use PHP to scan. And with that with that switch over to Job Script, we introduced a little bit of a bug, and I think we self-identified this bug.

Correct. Or, yeah.

William: Partially, we had self-identified it. So I actually believe someone posted about this in our Facebook group. Oh, okay. And expected that something else was at play. And as part of looking into what they expected was going on, we discovered that this actually was unable to be scanned by or the scan could no longer be kicked off because we don’t have the PHP scan that it was trying to kick off.

Right,

Steve: right, right. And [00:35:00] so what I’ll do is I’ll demo this once I can switch back to English.

William: Yeah. But I actually have the page up if you wanna Oh,

Steve: sure. I’ll show your screen.

William: Yeah, you show mine. So now I have it. So yeah, this is a page, it has these issues. So if I click this clear issues button, this is all zero out.

Effectively, all of these issues have gone away.

Steve: So describe where, so describe what page you’re on. You’re on, you were in the backend. Yes.

William: So I’m in the admin for the editor for, you know, a test post that I have in my local install. And where we have our results posted, we have the clear issues button for, click this, we get the alert that says this will clear all issues for the post.

So if I click okay, all the issues are cleared. So now I have the front end of that same post opened, and if I were to click on the front end high layer right now, [00:36:00] there’s gonna be no issues at all for us to see. But when I click this open, it said, load in, and now it says it’s scanning. And once the scan completes, there’s the issues think it’s, yeah, it’s the same number of issues and there are now all navigable, right?

This page has just scanned and it is scanned. This actual page that I’m looking at. It hasn’t. It spun up anything in the background. It hasn’t, you know, created a artificial or a ghost version of this page. It scanned this literal page now, as opposed to in the past, we would always backend it with PHP and make a request on the PHP side to do the scan.

Now we actually can scan this live page. There’s no difference with what it sees here in the editor when I save this and the front end, they’re exactly the same render page. And again, now there is results. If I come back to the [00:37:00] editor and I just reload the other, yeah, the issues are here. The page is being scanned.

Yeah, the bug was, this would never actually scan. It would just always be stuck and the front end highlighter would just always seal load. And whenever you tried to open a page that didn’t have scan results.

Steve: Yeah.

William: And there’s two reasons why a page could not have scan results. Right? I cleared the issues in the editor.

A page could literally never have been scanned, which you know, is what I’ve just emulated. But this page could also not have issues. It could legitimately be free of all the issues that we would discover with our plugin in cases like that, with the bug, the front ator would never tell people that their page had no issues.

It would just be stuck in that loading state.

Steve: Right. And it does a check to see if there are issues. And if there are issues, then it doesn’t run a recent scan for performance, right?

William: Correct. So now if I reload this [00:38:00] page, it actually just requests the issues from the previous scan. This scan only happens if there’s no issues to validate that this is a page with no issues.

You know, as we’ve seen in my demo where I cleared the issues, it discovered this page does have issues and thus they are presented. If it doesn’t discover issues, it tells you that. Right. No issues found. Right. Is what this would say. On this test site, I do not have a page right now that I know of that has no issues to demo that because this theme is video old and horrible.

Steve: Yeah. And this lays the groundwork for more front in scanning enhancements in the future. Yes.

William: So while this right now will only scan when there is no issues discovered on the page, we could have a button here in future that allows you to manually scan this and that will be, so on a site like this one, a test site that’s not very useful, but on a site that might have a front end page builder.

Being [00:39:00] able to re-scan right from the front end will be incredibly useful. ’cause you might make changes like this could be one of those like page builders where I could edit this content right now and if I edit that, these results would actually differ if I were to re-scan it. So yeah, in future probably will be a re-scan button here so that front end editors can re-scan their content as the edit.

Steve: Yeah. And the Accessibility Checker has fixes and if you hit an issue on this that has a fix there, you passed one. So you click the fix button and you can enable a fix from the front end where now we prompt you to go back to the back end and re-scan the page. We can, in a future release we can wrap in our re-scan into this and just automatically re-scan the page in real time.

William: Yep. Whenever you click that, it would just rescale and this number will immediately reflect the change. [00:40:00] Yeah. So 12, one morning I would have to visit the editor. Remove the page. Yeah.

Steve: Yeah. And for those that don’t know, the way our fixes work is we don’t implement fixes and just hope for the best. We implement fixes and then we require the Accessibility Checker to scan and ensure that our fix actually worked.

So now it’s gone. Right?

William: So it is not, so it’s actually this one that, oh no, this actually can be fixed because this is a hardcoded widget. So it thinks this is the WordPress core widget. But it isn’t just, and that is just the symptom of how this

Steve: No, but that’s a

William: local test page works.

Steve: That’s a beautiful example of what I just described.

William: Yes. So it cannot fix it, and thus this is not going away.

Steve: Right. Yeah, [00:41:00] just to sum that up even if you enable a fix in our plugin, we will re-scan and we will ensure that fix worked, because that’s a problem with, you know, programmatically fixing things. Right? Is that not every website is created exactly the same.

Not, you know, not every piece of markup will be behave the same when you apply JavaScript to it, or you filter it with a filter. So we actually will recheck to ensure that these things actually are fixed.

William: Yeah. And in this case here, the misinformed label, this cannot be fixed because it doesn’t have any data.

Surrendering this to know what to actual label this from. Right as a type field with an empty placeholder additional tail. It does have a name, but the name is nondescript. So yeah, this issue cannot automatically be fixed by error effects. ’cause this is just a hard coded input. It’s not an actual [00:42:00] search box.

How Accessibility Checker Validates Fixes Work

Steve: Yeah. Yeah. Cool. Here, lemme show this. Dave had another comment about the role tab. He said, oh, nice. Yeah. A role of tab role equals tab is not an improper use of a link.

William: It is uncommon, but it is valid. And we did already cover cases where role equals button on a link was also technically valid.

Just,

Steve: yeah.

William: And, you know, we would not flag that as an issue, even though I think if you’re, you know, making a link, be a button, maybe just use a button. But

Steve: yeah. Yeah.

William: It’s, that’s

Steve: technically

William: valid.

Steve: That’s definitely the answer. But and then effort for the Accessibility Checker to keep getting smarter and refining it.

I think this was a good move and it’ll help reduce some noise in maybe what would look like a false positive. It is a real po it kind, it’s one of those weird ones where you have to decide it’s [00:43:00] actually an issue, but like in the context of them building tabs, the screen reader, you test it and the screen reader would actually read out properly.

In that case,

William: it, it would, and yeah, way the markup might look weird to a person reading the HTML it’s semantically. Correct. The screen reader or any excessive technologies really is going to understand exactly what that element, what its purpose is. You know, the markup implies it’s a link, but its purpose is very different.

Yeah. Yeah.

Steve: Cool. So that kind of sums up the new features. Did you have anything else William on?

William: Yeah, actually, can you put my screen back up? Actually, I did wanna show how we’re validating these. So we actually, you know, as an nerd and a developer, we’ve actually created these test suites using est. So if we look at this markup here, this is an anchor tag with a role of tab.

And if I run this test, you know this [00:44:00] code here will pass, right? This, the last one passes with role of tab. I were to remove this rule of tab, press this play button again, it’ll run these tests and say, this one here fails. So we’ve actually, this is how we’re validating. That what our rules are doing is correct with what the expectation is.

So our expectation is that this passes and does not get flagged by our test and, you know, rerun the test. That is true. And when I was developing this or when this was discovered, I added this test case, and this test always failed, which meant when I was working on the link in proper role, I can make edits to this [00:45:00] check.

And the edits actually were quite simple. It’s literally just right here. But if I temporarily delete that for a second and we run this test, this was the initial state. So what we did, so this is, you know, test driven development, we’ve created a test. With the markup that we expect to pass, but it doesn’t.

So then you have to make edits to your rule check code. In the case it was, you know, simple, just add that. And we run the test. Now the test passes. So we validated that this markup that we expect pass actually does pass with a rule. And then, you know, beyond that, we actually will just literally come in to the editor and also test it right here.

But being able to manually

verify them very quickly with these automated tests, helps a lot. [00:46:00] And, you know, we have these tests for almost every single row that we have in our plugin.

How Accessibility Checker Rules are Better than axe-core

Steve: Let me ask you that. Let me why do we need to, why are we writing tests for our rules if we’re using axe-core?

William: What axe-core does is sometimes the minimum, and so axe very much leans towards never providing a false positive. But what we actually lean towards is providing the right information in the context of, you know, first off into the context of WordPress, we’re blissfully aware that WordPress does things a little bit differently to what the expected norms of the web are.

So in some cases we actually know it’s fine in WordPress because there’s additional things. You know, we want to test like spacer blocks, for example, axe core flags, those spacer blocks because they have aria-hidden, right? But we are aware that aria-hidden [00:47:00] is the correct markup for spacer block in WordPress, and as such, we skip over that, right?

So the point of our us writing our own tests is that. axe-core doesn’t always do exactly what we want or exactly what we expect. Sometimes it actually does the opposite and, but you know, sometimes the rules or the violations, it returns for its rules. We actually want those violations because discovering those violations implies other failures or, you know, other passes.

And we do have one rule in our plugin where we actually had to revert the logic that axe sends back axe will send back incomplete results as opposed to violations in certain cases. And when it returns incomplete results, we actually know that is a failure for the content that we’re checking.

Right. Yeah. All that to say is that axe does not necessarily [00:48:00] give the exact answer that you want. axe will do its best to never provide a false positive. We don’t always agree that is correct. Sometimes we will accept a false positive in exchange for, you know, avoiding false negatives, right? Like we, we would rather catch more things than miss things,

Steve: right?

Because we’re building a tool that is going aid in actual auditing, and –

William: Yes, we are not building an automated system to fix all the things and, you know, tick a box off on some report somewhere. We’re building software that we want you to be using every day while you’re making content. And as part of that, we, you know, we want you to, you know, sometimes have to manually validate something that you know, for your own reasons or for our, if we are uncertain, we’re gonna ask you to manually check something, right?

And I would rather present that information to you. Whereas axe ethos is that they’re uncertain, [00:49:00] they’re not gonna say anything.

Steve: Right?

William: And you know that. It is fine for the purposes of auditing and reporting, but it’s not fine for the purposes of content creation as someone’s creating content, tell them all the information you have.

It’s my thought on that.

Steve: Yeah, so we’ve heavily extended axe-core and created a lot of our own custom rules and checks that kind of are in line with what we had on the PHP side that we needed to kind of refactor and port over so that it wasn’t the reports inside of your dashboard when you’re using Accessibility Checker or weren’t jarring, or that we didn’t open axe-core up.

Then open the floodgates up and give you everything that axe-core can check for because that would be so much noise. We’ve carefully curated. What we pull in for axe-core and what we add to axe-core and what we, and you know, where Williams said, we modify, we invert the results to get [00:50:00] what we want, or we extend, we, we extend certain rules to have additional checks in there as well.

Oh, we’ve got our fearless leader here, Amber Hinds she said that is a great summary of our philosophy. Thanks, William. You know what? Yeah, I’ll say thanks William too. That’s two thanks from

William: That’s good. Coming from my boss and my other boss.

Steve: Yeah. Yeah. And Dave. Yeah. And Dave also replied that, that’s really good information.

William: Yeah. I very much disagree with the never provide false false positive right? I think provide as someone’s creating the content. It is not overwhelming at all for them to get a couple of false positives or a couple, you know, whereas if you’re scanning an entire website, you know, maybe you don’t want all those false positives, but as you’re [00:51:00] creating the content, I think it’s a non-issue.

Right. For additional issues, manually verified versus potentially missing dozens or hundreds.

What’s Coming Next

Steve: Yeah I totally agree. Cool. So we’re, we don’t have a lot of time, but I wanna run through this. We’ve talked about the features that we’ve recently released, and we’ve talked a little bit of nerdy technical talk about those, but let’s tease a little bit what’s coming for Accessibility Checker.

So I’ll grab the first one here. So we’re, have we got better rules for help inside of the plugin ui? We’re gonna have WCAG criteria, conformance level and the priority of the issue displayed coming up in a future release, which I believe is not the release coming out next Tuesday, but the release two weeks from that.

So here in about two and a half, three weeks, we should have that. And this is just better help documentation to help you understand what the issue is [00:52:00] and help you on what steps to take to remediate it. And this kind of pulls some of our documentation into the plugin to help give you more context to where to focus and what is the most critical issues to work on.

And another feature that’s coming that has been in our roadmap for. Several years is that we will have the ability to add a, an a, a comment to global ignores. So currently if you go in and ignore an issue in a, on a single post edit page, you can add a little comment right on why you’re ignoring this issue.

But we haven’t had that for our global ignores. And and so we have now added that and we’re in the final testing stages of that. And that should be roleed into the next release. And, landmarks. So I talked a little bit about this earlier. Our landmark location enhancements we’re gonna have, [00:53:00] we’re gonna be implementing filters for those based on user role.

And we’re gonna be creating user capabilities for that as well, so that we’re not just gonna attach it to an editor. We’re gonna create a capability that if you’re using the user, you know, a user role management plugin, that you can attach that capability to any user role that you see fit. And you’ll be able to define which landmark locations are global and which ones are not global.

And a big feature that we’re working on that will be coming out. And this one has been on our roadmap since the beginning. And William, do you wanna talk about this one?

William: Yep. So this one is archive page scans or more genetically old taxonomies. Effectively can now or will in the near future be able to be scanned.

This, you know, opens up the door for, you know, first off archives, but in addition, this sets the gates like things in place to be able to [00:54:00] scan everything that is not a post type. Because part of our the way our plugin is built post type is the underpinning group organization. And with moving to scanning the archive pages, the changes we’re making is going to decouple that.

So no longer will the content type required to be an actual post type. It will be, you know, archives or taxonomies. We can scan taxonomies, but I’ve worked on websites where they have fake content. So content is accessible but comes from the database that isn’t a post type. Pretty soon we will also be able to scan.

Those pieces of content and store those results, present those results. So yeah, it’s exciting movement to come. It has been a long time coming on the archive scanning, but there was a lot of blockers in place that have finally been unblocked by work we have previously been working through.

Yeah. [00:55:00] So not the next release, probably the one after.

Steve: Yep. So that’s two and a half weeks. Three weeks. Yeah. Three weeks. Yeah. So yeah, that’s a huge feature and it’s been something I think we, we’ve been promising this feature. I think we have it listed on the website somewhere for quite a while. And I think this will be a great addition to the plugin to get these archive pages, which are dynamically generated.

I don’t wanna get too technical about it right now. We’re doing a technical deep dive on this when it comes out. But our scanner utilizes. Post IDs or posts that live inside the post table and archives are actually dynamically generated and they don’t live anywhere. That, that creates quite the technical challenge.

And William and I sat down and we went through it different, you know, options that we could use to try to do this. And I believe we’ve come up with something fairly clever that will allow us to scan these. And we wanna be mindful too when we [00:56:00] implement this not to create a bunch of noise again, right?

And so we’re trying to make it a little intelligent where it can identify templates rather than just, this is a taxonomy term. So if you have a taxonomy with a thousand terms, right? We’re gonna scan a thousand terms. Just like that’s a lot of noise. It’s basically gonna be the same issues on every page.

But if we can somehow determine how many different term templates are being used and only scan a sampling of each of a term, like one term of each template that would allow our full site scanner to remain performant. We could actually add a setting that would allow you to scan all of them if you need that for compliance reasons.

But we’re doing a lot behind the scenes to try to come up with something that adds this feature in and does it in a performant way that isn’t disruptive to the current scanning [00:57:00] workflow that we have. Yeah.

William: So in, in a standard WordPress install with, you know, any of the default themes, we’re actually only gonna have categories, tags.

And they’re not gonna have custom templates. So that’s two things to scan. But we will almost always scan two of every item. So for example, we will scan two categories. We will find a category that has the most posts, and we’ll find a category that has the least posts. And you might have a category with, you know, ideally none.

So we might scan three, but at a minimum we’re almost always gonna scan at least two. The one with the most, the one with the least posts to make sure that, you know, a zero post, or make sure your pagination is fine if you’ve got a post, you know, a category that has 10,000 posts in it. But yeah, I think we, we can’t by default scan every single taxonomy.

I’ve worked on websites where there are more tags than posts, right? It, that’s not an uncommon situation. You know, you write one blog [00:58:00] post, you might add 10 tags and you continue to add 10 tags on every web post posts they stack up. Yeah. Probably two at, you know, at minimum, one from every single taxonomy.

One from every single template, but at least two from every single taxonomy as well, because, you know, maximum minimum.

Steve: Right. Cool. So those are some of the upcoming features that we’re, we’ll be talking about in upcoming episodes. So we are scheduling these live streams to happen biweekly. So these will come out in in the weeks opposite of our releases.

And so that the next one will be in two weeks. That is our languages, landmarks and links and some other fixes in between. It’ll be interesting to see if we can come up with a nice alliteration for every live stream, but maybe not.

Get More Information

Steve: So I wanna encourage you to check out the Accessibility Checker if you haven’t already.

You can go to Equalize Digital dot [00:59:00] com slash Accessibility Checker. You can download the free plugin from there. And you can also get information about purchasing our premium plugins there as well. If you have any questions, feel free to reach out to us. Equalize Digital on X SteveJonesDev on X.

You can go to Equalize Digital dot com and contact us there with any feedback on the plugin or any questions you may have. And we look forward to chatting again in the next live.

See y’all later. See you. Thanks for being here.

Translations: Supporting 32 Languages

Accessibility Checker is now available in 32 languages. This major enhancement was inspired by community feedback at WordCamp Europe and underscores our commitment to inclusivity. To make this possible, we implemented an AI-powered translation workflow using PTC (by WPML). While not perfect, these translations offer immediate value and are being validated by native speakers where possible.

One major challenge we faced was handling JavaScript string translations. Unlike PHP strings, which use traditional .po and .mo files, JavaScript requires a different format (.json) and build configuration to preserve function names after bundling and minification. We’ve adjusted our webpack and WP-CLI setup to support this.

In addition to machine translations, we’ve built a glossary system to preserve brand terms like “Accessibility Checker,” and we continue to test and refine translations based on user feedback.

During the livestream, Steve and William demoed the plugin in French to show the translated interface and explain some of the challenges in managing language support. They noted that WordPress’s default behavior may prioritize partially translated GlotPress files over fully translated local bundles. We’re exploring ways to override this to ensure the best experience for end users.

Landmarks: Better Issue Context

We introduced a new feature that identifies the landmark region where each issue is found (e.g., header, nav, main, footer). This contextual data is now visible in the issue details tab of the plugin’s meta box and integrated with our front-end highlighter.

This change is the first step in enabling role-based issue filtering, so content editors will only see accessibility issues they can actually fix. Future updates will include capabilities for customizing this behavior via user role management plugins.

Links: Smarter Detection of Improper Use

Our rule for detecting improper links was updated to avoid flagging cases where anchor tags are correctly repurposed using role="tab". This was found in some in tabbed interfaces. We continually implement test-driven development to validate rule logic, ensuring we catch the right issues without introducing noise, and William demonstrates this in the video.

Backend Enhancements

We also added several small usability enhancements:

  • Admin toolbar links to Accessibility Checker settings and issue reports
  • Quick links on the plugin page to documentation, support, and plugin settings
  • A direct “Settings” link next to the plugin listing for faster access

We made several technical changes that improve plugin compatibility and performance:

Primary Key Update for Database Table

A support case from a DigitalOcean user led us to update our custom database table to use a primary key instead of a unique key. This improves compatibility with managed MySQL hosts that require explicit primary keys and supports better indexing at scale.

Front-End Highlighter Fix

We resolved a bug where the front-end highlighter would not run on pages without existing scan results. Now, if a page has no issues stored, it will trigger a fresh JavaScript scan and report the results in real time—laying the groundwork for more advanced front-end scanning features in future versions.

How Our Rules Go Beyond axe-core

While Accessibility Checker uses axe-core for many rules, we extend and modify them for WordPress-specific contexts. For example, we skip false positives for spacer blocks that use aria-hidden, and we sometimes accept minor false positives to avoid missing real issues.

This balance ensures that the plugin provides more meaningful, actionable feedback during content creation—especially important for large teams where content editors need clarity on what they can fix.

We are not building an automated system to fix all the things and, you know, tick a box off on some report somewhere. We’re building software that we want you to be using every day while you’re making content. And as part of that, we want you to sometimes have to manually validate something or if we are uncertain, we’re gonna ask you to manually check something.

I would rather present that information to you. Whereas axe’s ethos is that if they’re uncertain, they’re not gonna say anything. And you know that is fine for the purposes of auditing and reporting, but it’s not fine for the purposes of content creation as someone’s creating content, tell them all the information you have.

William Patton, Senior Developer at Equalize Digital

What’s Coming Next

We’re actively working on the following features:

Better Help for Each Issue

Each issue will soon display the WCAG success criterion, conformance level (A, AA, AAA), and severity level (low, medium, high, critical) to help users prioritize.

Global Ignore Comments

Users will be able to leave notes on globally ignored issues, just as they can on individual posts.

Landmark-Based Issue Filtering

Issues will be filterable by user role or capability, helping editors focus on what’s relevant to their permissions.

Archive Page Scanning

Our full site scanner will soon support dynamically generated taxonomy archive pages (categories, tags, and custom taxonomies). To prevent excessive duplication, the scanner will intelligently sample based on available templates and post counts.

We’re also looking into scanning non-post-type content in the future, expanding coverage across more dynamic and nontraditional WordPress use cases.

Join Us for the Next Livestream

The Accessibility Checker Changelog livestream airs biweekly, alternating with our plugin release schedule. Each episode will feature demos, technical deep dives, and previews of new features. Follow us on YouTube to get notified when we go live.

To learn more, download the plugin, or upgrade to Pro, visit our Accessibility Checker page.

If you have feedback or questions, connect with us on X:

  • Steve Jones: @SteveJonesDev
  • Equalize Digital: @EqualizeDigital

We look forward to sharing more soon. See you at the next changelog update.

Facebook0Tweet0LinkedIn0Shares0

Filed Under: Product News

About Equalize Digital

Equalize Digital's team has specialized in WordPress accessibility for more than a decade. We offer accessibility audits, WordPress accessibility remediation, user testing, and build bespoke, accessibility-first websites. Our WordPress Accessibility Checker plugin is used by large and small businesses, nonprofits, higher ed, and government websites worldwide. Try it free today.

Post navigation

Equalize Digital: Inside our accessibility audit process for the world's leading WordPress eCommerce platform (WooCommerce).Previous post: Making 7 Million eCommerce Websites More Accessible: Equalize Digital’s Role in Enhancing WooCommerce Core and Extensions
Elementor Accessibility Angela Bowman and David DenedoNext post: Elementor Accessibility: Angela Bowman & David Denedo

Easier, Faster Accessibility Testing

Equalize Digital Accessibility Checker gives you real-time accessibility feedback in the WordPress editor. Learn accessibility and make fixes earlier in the dev and content creation process. Full-site accessibility scanning without the per page fees.

Get Accessibility Checker

Footer

Equalize Digital Websites for Everyone

Your WordPress accessibility team. Accessibility plugins, rapid audits, and consulting to help you make your website usable by people of all abilities.

  • Facebook
  • GitHub
  • LinkedIn
  • Twitter
  • YouTube

Company

  • About Equalize Digital
  • WordPress Accessibility Meetup
  • Accessibility Statement
  • Blog
  • Events
  • Contact Us

Services

  • Accessibility Audits
  • User Testing
  • Remediation
  • Ongoing Monitoring
  • VPAT & ACR Preparation
  • Accessibility Training
  • For Agencies
  • Website Development

Accessibility Checker

  • Features
  • Pricing
  • Documentation
  • How to Get Support
  • My Account
  • Affiliate Dashboard
  • Become an Affiliate

© 2025 Equalize Digital · Privacy Policy · Terms of Service · Software Terms & Refund Policy

International Association of Accessibility Professionals member

Wait!

Before you go, join our email list to get

10% off

Accessibility Checker or any online course.

Name(Required)

We promise only to send you trustworthy accessibility content and event invitations. You can unsubscribe anytime, and we won’t share your information with anyone.