Client Search

AI Product Photography

New Search

Product Counter Script

Paste in browser console on any Shopify store to count total products

async function countShopifyProducts() {
    const TIMEOUT_MS = 10000;
    const RATE_LIMIT_DELAY = 2000;
    let totalProducts = 0;
    let page = 1;
    let hasMore = true;
    let retries = 0;
    const maxRetries = 3;
    const startTime = Date.now();

    console.log('šŸ” Starting Shopify product count...\n');

    // Check if this is a Shopify store
    try {
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
        const testResponse = await fetch('/products.json?limit=1', { signal: controller.signal });
        clearTimeout(timeoutId);

        if (!testResponse.ok) {
            if (testResponse.status === 404) {
                console.error('āŒ This doesn\'t appear to be a Shopify store (no /products.json endpoint)');
                return null;
            }
            throw new Error(`HTTP ${testResponse.status}`);
        }
    } catch (error) {
        if (error.name === 'AbortError') {
            console.error('āŒ Request timed out. The server is not responding.');
        } else {
            console.error('āŒ Cannot access product data:', error.message);
        }
        return null;
    }

    while (hasMore) {
        try {
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
            const url = `/products.json?page=${page}&limit=250`;

            const response = await fetch(url, { signal: controller.signal });
            clearTimeout(timeoutId);

            if (response.status === 429) {
                console.log(`ā³ Rate limited. Waiting ${RATE_LIMIT_DELAY/1000}s...`);
                await new Promise(r => setTimeout(r, RATE_LIMIT_DELAY));
                retries++;
                if (retries > maxRetries) {
                    console.error('āŒ Too many rate limit errors. Try again later.');
                    break;
                }
                continue;
            }

            if (!response.ok) throw new Error(`HTTP ${response.status}`);

            const data = await response.json();
            retries = 0;

            if (data.products && data.products.length > 0) {
                totalProducts += data.products.length;
                const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
                console.log(`šŸ“¦ Page ${page}: +${data.products.length} products (Total: ${totalProducts}) [${elapsed}s]`);
                page++;
            } else {
                hasMore = false;
            }
        } catch (error) {
            if (error.name === 'AbortError') {
                console.error(`āŒ Page ${page} timed out. Retrying...`);
                retries++;
                if (retries > maxRetries) {
                    console.error('āŒ Too many timeouts. Partial count:', totalProducts);
                    break;
                }
            } else {
                console.error('āŒ Error:', error.message);
                hasMore = false;
            }
        }
    }

    const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
    console.log(`\nāœ… TOTAL PRODUCTS: ${totalProducts}`);
    console.log(`ā±ļø Completed in ${totalTime}s (${page - 1} pages)`);
    return totalProducts;
}

countShopifyProducts();

Recent Searches 0