2026年5月26日

2026年5月26日

ShortPixelのエラーを解決する方法

はじめに

ShortPixelで画像をアップロードするたびに「API接続エラー」が表示される・WebP/AVIF変換を有効にしたがブラウザのネットワークパネルでは元のJPEGが配信されている・クレジットが不足して一括最適化が途中停止しその後クレジットを購入しても最適化が再開しない・最適化済み画像を元に戻したいがバックアップからの復元が失敗するといった問題は、APIキー設定・次世代フォーマット配信設定・クレジット管理が原因です。

症状・原因

  • ShortPixelの設定を保存すると「Invalid API Key」エラーが表示される
  • タグは出力されているがブラウザではJPEGが配信されている
  • 一括最適化を再開するボタンを押しても動作しない
  • 最適化後に画像の品質が低すぎてピクセルが粗く見える

解決手順

ステップ1:ShortPixelの状態を確認する

# ShortPixel設定確認
wp eval "
if (defined('SHORTPIXEL_IMAGE_OPTIMISER_VERSION')) {
    echo 'ShortPixel version: ' . SHORTPIXEL_IMAGE_OPTIMISER_VERSION . PHP_EOL;
}

// API設定を確認
\$options = get_option('wp-short-pixel-settings', []);
echo 'API key set: '          . (!empty(\$options['apiKey']) ? 'yes' : 'no') . PHP_EOL;
echo 'Compression type: '     . (\$options['compressionType'] ?? '1') . ' (1=lossy, 2=glossy, 3=lossless)' . PHP_EOL;
echo 'WebP create: '          . (!empty(\$options['createWebp']) ? 'yes' : 'no') . PHP_EOL;
echo 'AVIF create: '          . (!empty(\$options['createAvif']) ? 'yes' : 'no') . PHP_EOL;
echo 'Backup enabled: '       . (!empty(\$options['backupImages']) ? 'yes' : 'no') . PHP_EOL;

// APIクレジットを確認
\$api = new ShortPixelAPI(\$options['apiKey'] ?? '');
\$credits = \$api->getUserData();
if (\$credits && !is_wp_error(\$credits)) {
    echo 'Credits remaining: ' . (\$credits->APICallsRemaining ?? 0) . PHP_EOL;
    echo 'Credits used: '      . (\$credits->APICallsMade ?? 0) . PHP_EOL;
}

// 最適化状況を確認
global \$wpdb;
\$pending = \$wpdb->get_var(
    \"SELECT COUNT(*) FROM {\$wpdb->postmeta}
     WHERE meta_key = '_shortpixel_status'
     AND meta_value = '1'\"
);
echo 'Pending optimizations: ' . \$pending . PHP_EOL;
"

ステップ2:API接続とクレジット管理を修正する

// functions.php: ShortPixel API管理

// ① API接続エラーを記録して管理者に通知
add_action('shortpixel_api_error', function(string $error, string $url): void {
    error_log(sprintf('[ShortPixel] API error: %s (URL: %s)', $error, $url));

    // クレジット不足の場合のみメール通知
    if (str_contains($error, 'credits') || str_contains($error, 'quota')) {
        $last_notified = get_transient('shortpixel_credit_notified');
        if (!$last_notified) {
            wp_mail(
                get_option('admin_email'),
                sprintf('[%s] ShortPixelクレジットが不足しています', get_bloginfo('name')),
                "ShortPixelのAPIクレジットが不足しています。\n\nhttps://shortpixel.com でクレジットを購入してください。"
            );
            set_transient('shortpixel_credit_notified', true, DAY_IN_SECONDS);
        }
    }
}, 10, 2);

// ② 最適化をプログラムで手動実行
function shortpixel_optimize_attachment(int $attachment_id): bool {
    if (!function_exists('spMetaDao')) return false;

    $meta = spMetaDao()->getMeta($attachment_id);
    if (!$meta) return false;

    // 未最適化または失敗の場合に再実行
    if ($meta->getStatus() <= 0) {
        do_action('shortpixel_optimize_now', $attachment_id);
        return true;
    }

    return false;
}

// ③ 新しい画像アップロード時の最適化優先度を設定
add_filter('shortpixel_image_conversion_priority', function(int $priority, int $attachment_id): int {
    // アイキャッチ画像は高優先度
    if (has_post_thumbnail() && get_post_thumbnail_id() === $attachment_id) {
        return 1; // 最高優先度
    }
    return $priority;
}, 10, 2);

ステップ3:WebP/AVIF配信の問題を修正する

# WebP/AVIF配信の診断
wp eval "
// CDN配信設定を確認
\$options = get_option('wp-short-pixel-settings', []);
echo 'CDN: '            . (!empty(\$options['CDNdomain']) ? \$options['CDNdomain'] : 'not set') . PHP_EOL;
echo 'WebP serving: '   . (\$options['webpAlgo'] ?? '0') . ' (0=none, 1=picture, 2=htaccess, 3=CDN)' . PHP_EOL;

// .htaccessのWebPルールを確認
\$htaccess = ABSPATH . '.htaccess';
\$content  = file_exists(\$htaccess) ? file_get_contents(\$htaccess) : '';
echo 'ShortPixel htaccess rules: ' . (str_contains(\$content, 'ShortPixel') ? 'yes' : 'no') . PHP_EOL;

// WebPファイルの生成状況
\$upload_dir = wp_upload_dir();
\$jpg_count  = count(glob(\$upload_dir['basedir'] . '/**/*.jpg', GLOB_BRACE) ?? []);
\$webp_count = count(glob(\$upload_dir['basedir'] . '/**/*.webp', GLOB_BRACE) ?? []);
echo 'JPG files: '  . \$jpg_count . PHP_EOL;
echo 'WebP files: ' . \$webp_count . PHP_EOL;
echo 'WebP coverage: ' . (\$jpg_count > 0 ? round(\$webp_count / \$jpg_count * 100) . '%' : 'N/A') . PHP_EOL;
"

ステップ4:バックアップと復元を管理する

// functions.php: バックアップ管理

// ① バックアップディレクトリを確認・修復
function check_shortpixel_backup_dir(): string {
    $upload_dir = wp_upload_dir();
    $backup_dir = $upload_dir['basedir'] . '/ShortpixelBackups/';

    if (!is_dir($backup_dir)) {
        wp_mkdir_p($backup_dir);
        // セキュリティのため.htaccessを追加
        file_put_contents($backup_dir . '.htaccess', 'Options -Indexes');
    }

    return is_writable($backup_dir) ? $backup_dir : '';
}

// ② 特定画像を元の画像に復元
function restore_shortpixel_original(int $attachment_id): bool {
    if (!function_exists('spMetaDao')) return false;

    $meta = spMetaDao()->getMeta($attachment_id);
    if (!$meta || $meta->getStatus() <= 0) return false;

    // ShortPixelの復元機能を呼び出す
    do_action('shortpixel_restore_image', $attachment_id);

    error_log(sprintf('[ShortPixel] Restored original for #%d', $attachment_id));
    return true;
}

// ③ 最適化除外リストを設定
add_filter('shortpixel_skip_optimization', function(bool $skip, int $attachment_id): bool {
    // RAWフォルダーの画像はスキップ
    $file = get_attached_file($attachment_id);
    if ($file && str_contains($file, '/originals/')) {
        return true;
    }
    // SVGはスキップ
    if (get_post_mime_type($attachment_id) === 'image/svg+xml') {
        return true;
    }
    return $skip;
}, 10, 2);

ステップ5:一括最適化の再開と品質設定を調整する

// functions.php: 品質設定・一括最適化

// ① 圧縮品質をプログラムで調整
add_filter('shortpixel_lossy_quality', function(int $quality, int $attachment_id): int {
    $mime = get_post_mime_type($attachment_id);

    // アイキャッチ画像は高品質に
    $post_id = attachment_url_to_postid(wp_get_attachment_url($attachment_id));
    if ($post_id && has_post_thumbnail($post_id) && get_post_thumbnail_id($post_id) === $attachment_id) {
        return 90; // より高品質
    }

    // PNGは品質設定が異なるため調整
    if ($mime === 'image/png') return 85;

    return $quality; // デフォルトを維持
}, 10, 2);

// ② 一括最適化の進捗をログ
add_action('shortpixel_after_optimize_image', function(int $attachment_id, array $info): void {
    error_log(sprintf('[ShortPixel] Optimized #%d: %s%% saved (%d -> %d bytes)',
        $attachment_id,
        round(($info['OriginalFileSize'] - $info['LossySize']) / $info['OriginalFileSize'] * 100, 1),
        $info['OriginalFileSize'],
        $info['LossySize']
    ));
}, 10, 2);

// ③ WP-CLIから一括最適化を再実行
if (defined('WP_CLI') && WP_CLI) {
    WP_CLI::add_command('shortpixel reprocess', function(array $args, array $assoc_args): void {
        $limit = (int) ($assoc_args['limit'] ?? 100);

        global $wpdb;
        $ids = $wpdb->get_col(
            $wpdb->prepare(
                "SELECT post_id FROM {$wpdb->postmeta}
                 WHERE meta_key = '_shortpixel_status'
                 AND meta_value IN ('0', '-1', '-2')
                 LIMIT %d",
                $limit
            )
        );

        WP_CLI::log(sprintf('Reprocessing %d images...', count($ids)));
        foreach ($ids as $id) {
            do_action('shortpixel_optimize_now', (int) $id);
        }
        WP_CLI::success('Done.');
    });
}

注意事項

  • ShortPixelのAPIキーは大文字・小文字を区別します。公式サイトからコピーする際にスペースが含まれていないか確認してください。設定画面で「APIキーを検証」ボタンをクリックして有効なキーであることを確認できます
  • WebP配信方式として「.htaccess」を選択した場合はApache環境のみで動作します。「picture要素」方式は全サーバーで動作しますがテーマのPHPファイルを修正する必要があります。最も互換性が高いのは「CDN」方式ですが追加費用が発生します
  • バックアップ機能を有効にすると最適化前の画像がバックアップフォルダーに保存されますが、ディスク使用量が2倍になります。ディスク容量が限られている場合はバックアップを無効にして代わりに定期的な手動バックアップを行ってください

まとめ

ShortPixel修復は①wp-short-pixel-settingsでAPIキー・圧縮タイプ・WebP/AVIF設定・クレジット残量を確認・_shortpixel_statusで保留中の最適化数を診断、②shortpixel_api_errorフックでクレジット不足時の管理者通知・shortpixel_optimize_nowで手動最適化を実行、③WebP配信方式(htaccess/picture/CDN)と.htaccessルールの確認・JPG対WebPカバレッジ率を計算、④バックアップディレクトリの存在・書き込み権限確認・shortpixel_restore_imageで元画像に復元・SVG除外設定、⑤shortpixel_lossy_qualityフィルターでアイキャッチを高品質に設定・WP-CLIで未最適化・失敗画像を一括再処理する手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ