Skip to content

Instantly share code, notes, and snippets.

@Bobz-zg
Last active August 24, 2025 09:54
Show Gist options
  • Save Bobz-zg/86f5a6060e0dda95003803b39edfc9e4 to your computer and use it in GitHub Desktop.
Save Bobz-zg/86f5a6060e0dda95003803b39edfc9e4 to your computer and use it in GitHub Desktop.
Additional content for Yoast SEO Content analysis Javascript plugin
/* global YoastSEO */
class YoastAnalysis {
constructor() {
// Initialize cached content storage for extra content to analyze
this.cachedContent = '';
// Track whether the data fetching process has completed
this.isDataFetched = false;
// Check that YoastSEO and its analysis worker are available before proceeding
if ( typeof YoastSEO === "undefined" || typeof YoastSEO.analysis === "undefined" || typeof YoastSEO.analysis.worker === "undefined" ) {
return; // Abort if YoastSEO objects are missing
}
// Begin async process: fetch additional data then register this plugin with YoastSEO
this.initializePlugin();
}
/**
* Initialize the plugin after fetching data.
* Asynchronously wait for content fetch, then register plugin and modifications.
*
* @returns {void}
*/
async initializePlugin() {
// Fetch the custom content via AJAX and store it in cachedContent
await this.fetchData();
// Notify YoastSEO’s app that this plugin is ready to modify content
YoastSEO.app.registerPlugin( "YoastAnalysis", { status: "ready" } );
// Register the content modification callback to add our custom content
this.registerModifications();
}
/**
* Register the modification that adds extra content to be analyzed by YoastSEO.
*
* @returns {void}
*/
registerModifications() {
// Bind `addContent` method to this instance so it can be called correctly later
const callback = this.addContent.bind( this );
// Register the callback with YoastSEO to modify the "content" input for analysis
// The numeric priority (10) controls the order relative to other modifications
YoastSEO.app.registerModification( "content", callback, "YoastAnalysis", 10 );
}
/**
* Callback to add our cached content to the existing content being analyzed.
*
* @param {string} data - The original content string passed in for analysis.
* @returns {string} The combined string including the extra cached content.
*/
addContent( data ) {
// Append cached content to the existing content string so it is included in analysis
data += this.cachedContent;
return data;
}
/**
* Fetches additional content data asynchronously from the server via AJAX.
* Stores the response in cachedContent for later use.
*
* @returns {Promise<void>} Resolves when fetching is complete or fails gracefully.
*/
async fetchData() {
// Prepare form data for AJAX POST request with action and current post details
const formData = new FormData();
formData.append('action', 'codesoup_get_yoast_post_content');
formData.append('post_type', window.pumpkin.post_type);
formData.append('post_id', window.pumpkin.post_id);
try {
// Perform AJAX request to WordPress admin-ajax.php URL set in window.pumpkin.ajax_url
const response = await fetch(window.pumpkin.ajax_url, {
method: 'POST',
credentials: 'same-origin', // Send cookies for same origin requests
body: formData
});
// Parse JSON from response
const result = await response.json();
// Debug: console.log( 'AJAX Response:', result );
// If successful, cache the returned content; if not, clear cache and log error
if ( result.success ) {
this.cachedContent = result.data || '';
} else {
console.error('AJAX Error:', result.data);
this.cachedContent = '';
}
// Mark data fetching as complete regardless of success or failure
this.isDataFetched = true;
} catch (error) {
// Handle network or parsing errors - reset cached content and mark fetching done
// console.error('Error fetching post content:', error);
this.cachedContent = '';
this.isDataFetched = true;
}
}
}
// Setup initialization of YoastAnalysis class on DOM ready.
document.addEventListener("DOMContentLoaded", () => {
// If YoastSEO API is already loaded, create a new instance immediately
if ( typeof YoastSEO !== "undefined" && typeof YoastSEO.app !== "undefined" ) {
new YoastAnalysis();
} else {
// Otherwise wait for YoastSEO to signal readiness, then instantiate
jQuery( window ).on(
"YoastSEO:ready",
function() {
new YoastAnalysis();
}
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment