Putting Character Caps on WordPress Post Titles

🔴⚠️ Classic Editor Only ⚠️🔴

This was a new one for me recently. I’ve never thought or needed to cap the number of characters that can be added to a post title in WordPress before. So when the request was made I started researching online to find a WordPress filter I could use to hook into the title field and apply a character cap. It didn’t take me long to discover there is no filter 🧐.

So what now? JavaScript my friend. Javascript. When one door closes in web development, another opens. So here is my solution using JavaScript. You will need to enqueue your script in the admin and that can be done by adding the following snippet to your funtions.php file (don’t forget to update the file path to your script).

/** * Load admin JS file */ if (! function_exists('my_custom_admin_js_hook')): function my_custom_admin_js_hook($hook) { wp_enqueue_script('my-custom-admin-js', get_template_directory_uri() . '/path/to/file.js', array()); } endif; add_action('admin_enqueue_scripts', 'my_custom_admin_js_hook');

We’ll be writing this in vanilla JavaScript, so everything is going to be wrapped in an event listener waiting for the DOM to load before proceeding.

document.addEventListener('DOMContentLoaded', () => { });

The next step is to add a try catch statement. This will let our script fail gracefully if there is an error and prevent us from breaking anything that runs after our script.

document.addEventListener('DOMContentLoaded', () => { try { // Our code will go here } catch (error) { console.log(error); } });

Now we will target the element that wraps the title in the admin and write an if statement to check it exists before moving on to the next step.

document.addEventListener('DOMContentLoaded', () => { try { const titleWrapper = document.getElementById('titlewrap'); if (titleWrapper) { // Add our code here } } catch (error) { console.log(error); } });

We want to add some kind of indicator to the title to let the user know how many characters are available. To do this we need to insert a new element into the DOM. This next step does that and adds a little inline style to it.

document.addEventListener('DOMContentLoaded', () => { try { const titleWrapper = document.getElementById('titlewrap'); if (titleWrapper) { const limitAlert = document.createElement('span'); limitAlert.classList.add('limit-alert'); titleWrapper.appendChild(limitAlert); limitAlert.style.display = 'block'; limitAlert.style.textAlign = 'right'; limitAlert.style.fontWeight = '600'; limitAlert.style.letterSpacing = '0.1px'; limitAlert.style.paddingTop = '5px'; } } catch (error) { console.log(error); } });

The next step is to add the maxlength attribute to the title input field (change the cap to whatever you like).

document.addEventListener('DOMContentLoaded', () => { try { const titleWrapper = document.getElementById('titlewrap'); if (titleWrapper) { const limitAlert = document.createElement('span'); limitAlert.classList.add('limit-alert'); titleWrapper.appendChild(limitAlert); limitAlert.style.display = 'block'; limitAlert.style.textAlign = 'right'; limitAlert.style.fontWeight = '600'; limitAlert.style.letterSpacing = '0.1px'; limitAlert.style.paddingTop = '5px'; const input = titleWrapper.querySelector('input[name="post_title"]'); input.setAttribute('maxlength', 60); } } catch (error) { console.log(error); } });

And now for a little bit of logic. Here we check the amount of characters in the title field against our max length. We run it on load by default. We then add some further logic that hooks into the Keyup event. Notice how we update the style of the limit alert.

document.addEventListener('DOMContentLoaded', () => { try { const titleWrapper = document.getElementById('titlewrap'); if (titleWrapper) { const limitAlert = document.createElement('span'); limitAlert.classList.add('limit-alert'); titleWrapper.appendChild(limitAlert); limitAlert.style.display = 'block'; limitAlert.style.textAlign = 'right'; limitAlert.style.fontWeight = '600'; limitAlert.style.letterSpacing = '0.1px'; limitAlert.style.paddingTop = '5px'; const input = titleWrapper.querySelector('input[name="post_title"]'); input.setAttribute('maxlength', 60); const currentLength = input.value.length; limitAlert.innerText = input.value !== '' ? `${60 - currentLength}/60 characters remaining` : `60/60 characters remaining`; limitAlert.style.color = input.value.length < 60 && input.value.length >= 0 ? '#6ea029' : '#dc3232'; input.addEventListener('keyup', function (e) { const chars = e.target.value; const cap = 60; const remaining = cap - chars.length; limitAlert.innerText = `${remaining}/60 characters remaining`; limitAlert.style.color = remaining < 60 && remaining > 0 ? '#6ea029' : '#dc3232'; }); } } catch (error) { console.log(error); } });

Bingo, that’s it. A nice little snippet of code to cap your post titles.

;