All-in-One SEO (AIOSEO) migration is also supported by the built-in tool.
What Gets Migrated
AIOSEO stores data in a custom aioseo_posts table:
| AIOSEO Column | SEO Forge Meta Key |
|---|---|
title | _seoforge_meta_title |
description | _seoforge_meta_description |
keyphrases (JSON, primary) | _seoforge_focus_keyword |
robots_noindex | _seoforge_noindex |
robots_nofollow | _seoforge_nofollow |
canonical_url | _seoforge_canonical_url |
og_title | _seoforge_og_title |
og_description | _seoforge_og_description |
og_image_url / og_image_custom_url | _seoforge_og_image |
twitter_title | _seoforge_twitter_title |
twitter_description | _seoforge_twitter_description |
AIOSEO custom canonical URLs (canonical_url) are imported into _seoforge_canonical_url. AIOSEO v4 rows with no supported payload are skipped by both detection and migration, so the UI count matches the migrated count.
Manual AIOSEO Migration
php
global $wpdb;
// Check if AIOSEO table exists
$table = $wpdb->prefix . 'aioseo_posts';
$exists = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) );
if ( $exists ) {
$rows = $wpdb->get_results(
"SELECT * FROM {$table}
WHERE title != ''
OR description != ''
OR keyphrases != ''
OR robots_noindex = 1
OR robots_nofollow = 1
OR canonical_url != ''
OR og_title != ''
OR og_description != ''
OR twitter_title != ''
OR twitter_description != ''"
);
foreach ( $rows as $row ) {
$post_id = $row->post_id;
if ( ! empty( $row->title ) ) {
$title = str_replace(
[ '#post_title', '#site_title', '#separator_sa' ],
[ get_the_title( $post_id ), get_bloginfo( 'name' ), '|' ],
$row->title
);
update_post_meta( $post_id, '_seoforge_meta_title', sanitize_text_field( $title ) );
}
if ( ! empty( $row->description ) ) {
$desc = str_replace(
[ '#post_title', '#post_excerpt', '#site_title' ],
[ get_the_title( $post_id ), get_the_excerpt( $post_id ), get_bloginfo( 'name' ) ],
$row->description
);
update_post_meta( $post_id, '_seoforge_meta_description', sanitize_text_field( $desc ) );
}
// Extract primary keyphrase from JSON
if ( ! empty( $row->keyphrases ) ) {
$kp = json_decode( $row->keyphrases, true );
$primary = $kp['focus']['keyphrase'] ?? '';
if ( $primary ) {
update_post_meta( $post_id, '_seoforge_focus_keyword', sanitize_text_field( $primary ) );
}
}
if ( ! empty( $row->robots_noindex ) ) {
update_post_meta( $post_id, '_seoforge_noindex', '1' );
}
if ( ! empty( $row->robots_nofollow ) ) {
update_post_meta( $post_id, '_seoforge_nofollow', '1' );
}
}
}—