Tutorials

Making API Calls in Chrome Extensions

Learn how to make API calls in Chrome extensions using fetch, handle CORS issues, and apply best practices for service workers, content scripts, and secure storage.

Mellowtel Team

Mellowtel Team

๐ŸŒ Making API Calls in Chrome Extensions

Making API calls is essential for many Chrome extensions. This guide shows you how to do it securely and efficiently using modern JavaScript practices.


๐Ÿงฐ Prerequisites

Make sure your extension is properly set up. New to this? Start with our beginner guide.


๐Ÿชœ Steps to Make API Calls

1. Request Permissions

In your manifest.json:

{
  "manifest_version": 3,
  "name": "My API Extension",
  "version": "1.0",
  "permissions": ["https://api.example.com/"],
  "host_permissions": ["https://api.example.com/"]
}

Replace the URL with your API base path.


2. Make the API Call

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) throw new Error(\`HTTP error! status: \${response.status}\`);
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Error:', error);
  }
}

fetchData();

3. Handle CORS

To avoid CORS issues, call the API from a service worker rather than a content script.


๐Ÿ”„ Making API Calls from Different Contexts

โœ… From Service Workers

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'fetchData') {
    fetchDataAndRespond(sendResponse);
    return true;
  }
});

async function fetchDataAndRespond(sendResponse) {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) throw new Error(\`HTTP error! status: \${response.status}\`);
    const data = await response.json();
    sendResponse({data});
  } catch (error) {
    sendResponse({error: error.toString()});
  }
}

โœ… From Content Scripts

async function fetchDataFromBackground() {
  try {
    const response = await chrome.runtime.sendMessage({action: 'fetchData'});
    if (response.data) {
      console.log(response.data);
    } else {
      console.error(response.error);
    }
  } catch (error) {
    console.error('Error:', error);
  }
}

fetchDataFromBackground();

โœ… Best Practices

  • Use async/await for readability
  • Handle errors with try/catch
  • Throttle or cache to respect rate limits
  • Store API keys securely (use chrome.storage)
  • Handle offline scenarios gracefully

๐Ÿ” Security Considerations

  • Never hardcode sensitive API keys
  • Use HTTPS for all requests
  • Validate and sanitize all received data
  • Only request necessary permissions

โš™๏ธ Using the Fetch API with Options

async function postData(url = '', data = {}) {
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error(\`HTTP error! status: \${response.status}\`);
    return await response.json();
  } catch (error) {
    console.error('Error:', error);
  }
}

postData('https://api.example.com/data', { answer: 42 })
  .then((data) => console.log(data));

๐Ÿ”‘ Handling Authentication

async function fetchWithAuth(url) {
  const API_KEY = await getApiKey(); // Implement securely
  try {
    const response = await fetch(url, {
      headers: { 'Authorization': \`Bearer \${API_KEY}\` }
    });
    if (!response.ok) throw new Error(\`HTTP error! status: \${response.status}\`);
    return await response.json();
  } catch (error) {
    console.error('Error:', error);
  }
}

๐Ÿงพ Conclusion

You now know how to:

  • Make secure API calls
  • Use fetch with async/await
  • Handle CORS issues with service workers
  • Follow best practices for security and performance

Continue building dynamic extensions by combining APIs with service workers, content scripts, and UI pages.

Happy coding! ๐Ÿš€

On this page