Skip to main content

Command Palette

Search for a command to run...

Making API Calls in Chrome Extensions

Updated
4 min read
Making API Calls in Chrome Extensions
M

Easily monetize your browser extensions. Mellowtel is an open-source, ethical monetization engine that respects user privacy and maximizes your revenue.

Making API calls is a common requirement for many Chrome extensions. This guide will walk you through the process of making API calls from different parts of your Chrome extension using modern JavaScript practices.

Prerequisites

Before making API calls, ensure you've set up your basic extension structure. If you're new to this, check out our guide on How to Create Your First Chrome Extension.

Steps to Make API Calls

1. Request Permissions

First, request permission to make network requests 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 https://api.example.com/ with the base URL of the API you're calling. Note that in Manifest V3, we use both permissions and host_permissions for network requests.

2. Making the API Call

You can use the fetch API with async/await to make network requests. Here's a basic example:

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();

This code uses async/await to handle the asynchronous nature of the fetch call, making it easier to read and maintain.

3. Handling CORS

If you're making calls to a third-party API, you might encounter CORS (Cross-Origin Resource Sharing) issues. To resolve this, you may need to make the call from a service worker (background script) instead of a content script.

Making API Calls from Different Contexts

From Service Workers (Background Scripts)

Service workers in Manifest V3 can use async/await directly:

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

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: data});
  } catch (error) {
    sendResponse({error: error.toString()});
  }
}

From Content Scripts

While content scripts can make API calls directly, it's often better to relay the call through a service worker to avoid CORS issues:

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

  1. Error Handling: Always include proper error handling in your API calls.

  2. Use async/await: It makes asynchronous code more readable and easier to maintain.

  3. Respect API Rate Limits: Implement appropriate throttling or caching mechanisms.

  4. Secure Storage of API Keys: If your API requires authentication, store keys securely. Consider using the Chrome Extension Storage API for sensitive data.

  5. Handle Network Changes: Be prepared for offline scenarios or network interruptions.

Security Considerations

  1. Never expose sensitive API keys in your extension code. Use environment variables or secure storage methods.

  2. Always use HTTPS for API calls to ensure data privacy and integrity.

  3. Validate and sanitize all data received from APIs before using it in your extension.

  4. Be cautious about the permissions you request. Only ask for what you need.

Using the Fetch API with Options

For more complex API calls, you can pass options to the fetch function:

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);
  }
}

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

Handling Authentication

If your API requires authentication, you might need to include an API key or token in your requests. Here's an example:

async function fetchWithAuth(url) {
  const API_KEY = await getApiKey(); // Implement this function to securely retrieve your API key
  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

Making API calls is a powerful way to extend the functionality of your Chrome extension. By following this guide, you've learned how to make API calls from different parts of your extension, handle errors, and deal with common issues like CORS.

As you develop more complex extensions, consider how you can use API calls in conjunction with other extension features, such as service workers, content scripts, and options pages, to create a rich and dynamic user experience.

Remember to always prioritize security and user privacy when working with APIs in your extensions. Happy coding!