The Solution
To guarantee a functional skip link across any WordPress theme without modifying core theme files, the most reliable strategy is to use a must-use (MU) plugin that injects the link via the wp_body_open hook and ensures a target ID exists on the main content container.
Implementation Steps
- Create a Must-Use Plugin: Create a file at
wp-content/mu-plugins/accessibility-skip-link.php. MU plugins are automatically activated and cannot be disabled by site administrators in the dashboard.
- Inject the Link: Use the
wp_body_open hook to place the link immediately after the opening <body> tag.
- Standardize the Target: Since different themes use different IDs (e.g.,
#content, #main, #primary), the plugin should inject a small piece of JavaScript to ensure the primary content area has a consistent ID if the theme lacks one.
<?php
add_action('wp_body_open', function() {
echo '<a class="skip-link screen-reader-text" href="#main-content">Skip to content</a>';
});
add_action('wp_footer', function() {
?>
<script>
(function() {
const targets = ['main', 'primary', 'content'];
let found = false;
targets.forEach(id => {
if (document.getElementById(id)) {
document.getElementById(id).id = 'main-content';
found = true;
}
});
if (!found) {
const main = document.querySelector('main') || document.querySelector('.site-main');
if (main) main.id = 'main-content';
}
})();
</script>
?>
Explanation of Strategy
Confirmed Facts: The wp_body_open action was introduced in WordPress 5.2 to provide a standardized location for injecting scripts and elements at the start of the body. Using this hook avoids the need to edit header.php in individual themes.
Likely Behavior: While most modern themes include a <main> element, older themes may rely on <div> wrappers. The JavaScript fallback provided above attempts to map common theme IDs to a single target (#main-content) to prevent broken links across different theme architectures.
Verification
- Keyboard Test: Load the page and press
Tab immediately. The "Skip to content" link should appear visually.
- Focus Test: Press
Enter on the link; the browser focus must move to the main content area, bypassing the navigation menu.
- DOM Inspection: Ensure only one element with the ID
main-content exists to avoid accessibility failures.
Diagnostic Requirement
Are you using a Block Theme (FSE) or a Classic Theme? Block themes handle template parts differently, and if you are using a Full Site Editing theme, this injection can be handled directly via the Site Editor's HTML patterns without a plugin.