/**
* GTmetrix Performance Analyzer
* API v2.0: https://gtmetrix.com/api/docs/2.0/
* Requires API key (free tier available with limited credits)
*/
export interface GTmetrixOptions {
/** API key (required - get from https://gtmetrix.com/api/) */
apiKey: string;
/** Test location (e.g., 'vancouver-canada') */
location?: string;
/** Browser (e.g., 'chrome', 'firefox') */
browser?: string;
}
export interface GTmetrixResponse {
data: {
id: string;
type: string;
attributes: {
state: string;
error?: string;
report_url?: string;
lighthouse_score?: number;
pagespeed_score?: number;
yslow_score?: number;
fully_loaded_time?: number;
page_bytes?: number;
page_elements?: number;
};
};
}
export interface GTmetrixResult {
tool: 'gtmetrix';
success: boolean;
url: string;
test_id?: string;
status: 'queued' | 'started' | 'completed' | 'error';
lighthouse_score?: number;
pagespeed_score?: number;
yslow_score?: number;
fully_loaded_time?: number;
page_bytes?: number;
page_elements?: number;
report_url?: string;
error?: string;
raw?: GTmetrixResponse;
}
/**
* Analyze website using GTmetrix API
* Note: Requires API key. Free tier has limited credits.
*
* Get API key: https://gtmetrix.com/api/
*/
export async function analyzeGTmetrix(
url: string,
options: GTmetrixOptions
): Promise<GTmetrixResult> {
try {
if (!options.apiKey) {
throw new Error('GTmetrix API key is required. Get one at https://gtmetrix.com/api/');
}
// Start test
const testResponse = await fetch('https://gtmetrix.com/api/2.0/tests', {
method: 'POST',
headers: {
'Authorization': `Basic ${Buffer.from(options.apiKey + ':').toString('base64')}`,
'Content-Type': 'application/vnd.api+json',
},
body: JSON.stringify({
data: {
type: 'test',
attributes: {
url,
location: options.location || 'vancouver-canada',
browser: options.browser || 'chrome',
},
},
}),
});
if (!testResponse.ok) {
throw new Error(`GTmetrix API error: ${testResponse.status} ${testResponse.statusText}`);
}
const testData: GTmetrixResponse = await testResponse.json();
const testId = testData.data.id;
// Poll for results (simplified - returns immediately with test ID)
// For complete implementation, would poll until state === 'completed'
return {
tool: 'gtmetrix',
success: testData.data.attributes.state !== 'error',
url,
test_id: testId,
status: testData.data.attributes.state as any,
lighthouse_score: testData.data.attributes.lighthouse_score,
pagespeed_score: testData.data.attributes.pagespeed_score,
yslow_score: testData.data.attributes.yslow_score,
fully_loaded_time: testData.data.attributes.fully_loaded_time,
page_bytes: testData.data.attributes.page_bytes,
page_elements: testData.data.attributes.page_elements,
report_url: testData.data.attributes.report_url,
error: testData.data.attributes.error,
raw: testData,
};
} catch (error) {
return {
tool: 'gtmetrix',
success: false,
url,
status: 'error',
error: error instanceof Error ? error.message : String(error),
};
}
}