This section covers everything you need to begin integrating your theme or plugin with Rank Forge. You will learn how to detect the plugin, check versions, gate features by license tier, and access the internal class instances.
Shared Forge Suite Diagnostics
When Rank Forge is active, the shared Forge Suite > Setup & Health panel is available in WordPress admin. The diagnostic AJAX action is forge_suite_health_check; the guided-action endpoint is forge_suite_health_repair. Both require manage_options and the localized forge_suite_health_check nonce. The response returns diagnostics for active Forge plugins, local license records, credits widget readiness, Avakode API /health, permalinks, migration/integration source plugins such as Yoast, Rank Math, AIOSEO, WooCommerce, and Elementor, recommendations, and recent run history. Allowed repair actions are narrow: refresh permalink rules, refresh saved credit balances, generate a redacted support package, or clear diagnostic history. The panel does not run audits, call AI endpoints, spend credits, import SEO data, write Google settings, or change license/Freemius state.
The shared manual license fallback uses wp_ajax_forge_suite_resolve_license_scope before activation. It requires activate_plugins, the localized forge_suite_resolve_license_scope nonce, and POST fields license_key plus product; it calls Avakode /licenses/validate with resolve_products:true and returns the Worker’s valid, license_product, is_bundle, matched_product, and error_code fields so the JS activates only a Bundle fan-out or the one matching standalone plugin.
Checking if Rank Forge is Active
Before calling any Rank Forge API, you must verify the plugin is loaded. The recommended approach depends on where your code runs:
// Basic check — works anywhere after plugins_loaded
if ( class_exists( 'RANKFORGE_Core' ) ) {
// Rank Forge is active and loaded
}
// Version check — useful when your integration depends on a specific API
if ( defined( 'RANKFORGE_VERSION' ) && version_compare( RANKFORGE_VERSION, '1.0.0', '>=' ) ) {
// Version 1.0.0 or higher — safe to use all documented APIs
}
// Full guard pattern for theme functions.php or plugin bootstrap
add_action( 'plugins_loaded', function () {
if ( ! class_exists( 'RANKFORGE_Core' ) ) {
return; // Rank Forge not installed or not active
}
// Safe to register hooks that interact with Rank Forge
add_filter( 'robots_txt', 'my_custom_robots_rules', 25, 2 );
add_action( 'wp_head', 'my_extra_schema_output', 8 );
}, 10 ); // priority 10 runs after Rank Forge's priority 5The timing matters because Rank Forge initializes on plugins_loaded at priority 5. Any code that depends on Rank Forge classes should run at priority 6 or later.
Available Constants
Rank Forge defines the following constants during bootstrap. Use them for building file paths, referencing assets, or checking versions:
RANKFORGE_VERSION // '1.0.0' — current plugin version string
RANKFORGE_DIR // '/path/to/wp-content/plugins/rankforge/' — absolute filesystem path with trailing slash
RANKFORGE_URL // 'https://example.com/wp-content/plugins/rankforge/' — URL with trailing slash
RANKFORGE_BASENAME // 'rankforge/rankforge.php' — plugin basename for use with plugin_dir_path(), etc.Example usage in a companion plugin:
// Enqueue a script that depends on Rank Forge admin JS
add_action( 'admin_enqueue_scripts', function () {
if ( ! defined( 'RANKFORGE_VERSION' ) ) {
return;
}
wp_enqueue_script(
'my-rankforge-addon',
plugin_dir_url( __FILE__ ) . 'js/addon.js',
[ 'rankforge-admin' ],
'1.0.0',
true
);
wp_localize_script( 'my-rankforge-addon', 'myAddon', [
'rankforgeDir' => RANKFORGE_DIR,
'rankforgeUrl' => RANKFORGE_URL,
'version' => RANKFORGE_VERSION,
] );
} );License and Feature Gating
Features are gated by license tier. Always check availability before calling PRO methods, otherwise you will get a fatal error or unexpected behavior:
// Check if PRO is active (returns bool)
if ( RANKFORGE_License::is_pro() ) {
// All PRO features available
}
// Check a specific feature by key (returns bool)
// NOTE: 'redirects' is part of the Free core since 2026-05-29, so can()
// returns true on every tier. Use a genuine Pro key (e.g. 'gsc') to gate
// premium functionality.
if ( RANKFORGE_License::instance()->can( 'gsc' ) ) {
$gsc = RANKFORGE_GSC::instance();
$rankings = $gsc->get_rankings();
}
// Get current plan as string: 'free', 'pro', or 'trial'
$plan = RANKFORGE_License::get_plan();
// Conditional UI rendering based on plan
if ( RANKFORGE_License::get_plan() === 'free' ) {
echo '<p>Upgrade to PRO for Google Search Console rankings.</p>';
} else {
// Render GSC rankings UI
}can():
| Key | Feature | Tier |
|---|---|---|
meta_generator | AI Meta Generation | PRO, Trial |
content_brief | AI Content Brief | PRO, Trial |
schema_builder | Schema Builder (manual) | Free |
site_audit | Site Audit | PRO, Trial |
internal_links | Internal Link Suggestions | PRO, Trial |
auto_links | Auto Internal Links | PRO, Trial |
gsc | Google Search Console | PRO, Trial |
ab_testing | A/B Testing | PRO, Trial |
image_seo | Image SEO | Free |
content_optimizer | Content Optimizer | PRO, Trial |
redirects | Redirects Manager | Free |
local_seo | Local SEO (core) | Free |
local_seo_ai | Local SEO AI Auto-Fill | PRO, Trial |
video_seo | Video SEO | Free |
As of the 2026-05-29 Free/Pro rebalance, schema_builder (manual visual builder), image_seo, redirects (with 404 tracking), local_seo, and video_seo are part of the Free core — can() returns true for them on every tier. AI schema detection (auto-fill via /schema/detect/{post_id}) remains PRO-only. The only Pro gate inside Local SEO is the AI Auto-Fill button (local_seo_ai). Runtime handlers must still enforce the genuine Pro gates as the admin UI does. Current builds re-check can() inside AI schema output, REST /links/suggest/{post_id}, and GSC cron sync. The Settings page also gates PRO-only form controls and normalizes submitted values server-side: Free or expired saves force AI meta, internal-link suggestions, and auto internal links off even if a stale browser tab or crafted POST submits those fields. When Freemius is reachable and reports no active paid or trial access, Rank Forge clears forge_license_last_pro_at before the grace-period fallback; the timestamp only covers a missing/unavailable Freemius state, not an explicit expired, cancelled, or not-paying response.
Example: building a custom admin page that conditionally shows features:
add_action( 'admin_menu', function () {
if ( ! class_exists( 'RANKFORGE_License' ) ) {
return;
}
add_submenu_page(
'rankforge',
'My Addon',
'My Addon',
'manage_options',
'my-rankforge-addon',
function () {
$license = RANKFORGE_License::instance();
echo '<div class="wrap"><h1>My SEO Addon</h1>';
if ( $license->can( 'gsc' ) ) {
echo '<h2>Search Console Data</h2>';
$gsc = RANKFORGE_GSC::instance();
if ( $gsc->is_connected() ) {
$rankings = $gsc->get_keyword_rankings( 28, 10 );
// Render rankings table...
}
} else {
echo '<p>Upgrade to PRO to see Search Console data.</p>';
}
echo '</div>';
}
);
} );Singleton Pattern
All Rank Forge classes follow the singleton pattern. Never instantiate them with new — always use ::instance():
$analyzer = RANKFORGE_Analyzer::instance();
$schema = RANKFORGE_Schema::instance();
$redirects = RANKFORGE_Redirects::instance();
$gsc = RANKFORGE_GSC::instance();
$templates = RANKFORGE_Meta_Templates::instance();
$meta_gen = RANKFORGE_Meta_Generator::instance();
$links = RANKFORGE_Internal_Links::instance();
$auto_links = RANKFORGE_Auto_Links::instance();
$scorer = RANKFORGE_Content_Scorer::instance();
$optimizer = RANKFORGE_Content_Optimizer::instance();
$sitemap = RANKFORGE_Sitemap::instance();
$robots = RANKFORGE_Robots_Meta::instance();
$robots_txt = RANKFORGE_Robots_Txt::instance();
$image_seo = RANKFORGE_Image_Seo::instance();
$local = RANKFORGE_Local_Seo::instance();
$video = RANKFORGE_Video_Seo::instance();
$ab = RANKFORGE_AB_Testing::instance();
$dashboard = RANKFORGE_Dashboard::instance();You can safely call ::instance() multiple times — it always returns the same object.
—