Understanding the initialization order and hook priorities is critical for integrations.
Initialization Order
All classes are instantiated in seoforge_init() on plugins_loaded (priority 5):
text
1. SEOFORGE_License 12. SEOFORGE_Redirects
2. SEOFORGE_Core 13. SEOFORGE_Image_Seo
3. SEOFORGE_Analyzer 14. SEOFORGE_GSC
4. SEOFORGE_Meta_Templates 15. SEOFORGE_Local_Seo
5. SEOFORGE_Meta_Generator 16. SEOFORGE_AB_Testing
6. SEOFORGE_Internal_Links 17. SEOFORGE_Auto_Links
7. SEOFORGE_Schema 18. SEOFORGE_Site_Audit
8. SEOFORGE_Content_Scorer 19. SEOFORGE_Robots_Meta
9. SEOFORGE_Content_Optimizer 20. SEOFORGE_Sitemap
10. SEOFORGE_Rest_Api 21. SEOFORGE_Robots_Txt
11. SEOFORGE_Dashboard 22. SEOFORGE_Video_SeoAdmin-only classes (SEOFORGE_Admin, SEOFORGE_License_Admin, SEOFORGE_Migration) load only when is_admin().
Safe Timing for Integration Code
php
add_action( 'plugins_loaded', function () {
if ( ! class_exists( 'SEOFORGE_Core' ) ) {
return;
}
// All SEOFORGE_* classes are now available
}, 10 ); // Priority 10 is after SEO Forge's priority 5
// Run custom code after SEO Forge finishes analyzing on save
add_action( 'save_post', function ( $post_id, $post, $update ) {
if ( ! class_exists( 'SEOFORGE_Analyzer' ) ) {
return;
}
$cached = SEOFORGE_Analyzer::instance()->get_cached( $post_id );
if ( $cached && (int) $cached->score < 50 ) {
wp_mail( get_option( 'admin_email' ), "Low SEO score on #{$post_id}",
"'{$post->post_title}' scored {$cached->score}." );
}
}, 25, 3 ); // Priority 25 runs after SEO Forge's 20—