Skip to main content

Search Google

Perform Google searches and retrieve results including the knowledge graph.

Method

services.web.search(params);

Parameters

query
string
required
The search query. Never use the site: operator - use the domain parameter instead.
domain
string
Limit search results to a specific domain (e.g., “stripe.com”)
Enable advanced search features

Returns

Returns a Promise with:
results
array
required
Array of search results
knowledgeGraph
object
Google Knowledge Graph data (when available)

Examples

const results = await services.web.search({
   query: "artificial intelligence trends 2024",
});

console.log(`Found ${results.results.length} results`);

results.results.forEach((result, index) => {
   console.log(`\n${index + 1}. ${result.title}`);
   console.log(`   ${result.displayed_link}`);
   console.log(`   ${result.snippet}`);
});
// Find specific pages within a website
const results = await services.web.search({
   query: "API documentation",
   domain: "stripe.com",
});

// Get the most relevant result
const topResult = results.results[0];
console.log(`Best match: ${topResult.link}`);

Knowledge Graph Extraction

const results = await services.web.search({
   query: "OpenAI",
});

if (results.knowledgeGraph) {
   const kg = results.knowledgeGraph;

   console.log(`Company: ${kg.title}`);
   console.log(`Description: ${kg.description}`);
   console.log(`Website: ${kg.website}`);
   console.log(`Image: ${kg.image}`);

   // For businesses with hours
   if (kg.hours_links?.length > 0) {
      console.log("\nBusiness Hours:");
      kg.hours_links.forEach((link) => {
         console.log(`${link.text}: ${link.link}`);
      });
   }
}

Use Cases

Find Specific Pages

async function findPage(domain: string, pageType: string) {
   const results = await services.web.search({
      query: pageType,
      domain,
   });

   // Return the most relevant result
   return results.results[0]?.link;
}

// Find pricing page
const pricingUrl = await findPage("notion.so", "pricing");
console.log(`Pricing page: ${pricingUrl}`);

// Find documentation
const docsUrl = await findPage("stripe.com", "documentation");
console.log(`Docs: ${docsUrl}`);

Company Research

async function researchCompany(companyName: string) {
   const results = await services.web.search({
      query: companyName,
   });

   const info = {
      searchResults: results.results.slice(0, 5),
      knowledgeGraph: results.knowledgeGraph,
   };

   if (info.knowledgeGraph) {
      console.log(`\n${info.knowledgeGraph.title}`);
      console.log(info.knowledgeGraph.description);
      console.log(`Website: ${info.knowledgeGraph.website}`);
   }

   console.log("\nTop Results:");
   info.searchResults.forEach((result, i) => {
      console.log(`${i + 1}. ${result.title}`);
      console.log(`   ${result.link}`);
   });

   return info;
}

await researchCompany("Anthropic");

Find Contact Pages

async function findContactPage(domain: string) {
   const queries = ["contact", "contact us", "get in touch"];

   for (const query of queries) {
      const results = await services.web.search({
         query,
         domain,
      });

      if (results.results.length > 0) {
         return results.results[0].link;
      }
   }

   return null;
}

const contactUrl = await findContactPage("acme.com");
console.log(`Contact page: ${contactUrl}`);

Competitive Analysis

async function findCompetitors(companyName: string) {
   const results = await services.web.search({
      query: `${companyName} competitors alternatives`,
   });

   // Extract competitor mentions from snippets
   const competitors = new Set<string>();

   results.results.forEach((result) => {
      const snippet = result.snippet.toLowerCase();
      // Simple extraction - could be enhanced with NLP
      const words = snippet.split(/\s+/);
      // Look for capitalized words (potential company names)
      words.forEach((word) => {
         if (word.length > 3 && word[0] === word[0].toUpperCase()) {
            competitors.add(word);
         }
      });
   });

   return {
      query: companyName,
      potentialCompetitors: Array.from(competitors),
      sources: results.results.map((r) => r.link),
   };
}

Find Recent News

async function findRecentNews(topic: string) {
   const results = await services.web.search({
      query: `${topic} news`,
      advance_search: true,
   });

   // Filter for news sites
   const newsSites = ["techcrunch.com", "theverge.com", "reuters.com", "bloomberg.com", "wsj.com"];

   const newsResults = results.results.filter((result) => {
      return newsSites.some((site) => result.link.includes(site));
   });

   return newsResults.map((result) => ({
      title: result.title,
      url: result.link,
      snippet: result.snippet,
   }));
}

const news = await findRecentNews("artificial intelligence");
news.forEach((article) => {
   console.log(`\n${article.title}`);
   console.log(article.url);
   console.log(article.snippet);
});

Find Social Media Profiles

async function findSocialProfiles(companyName: string) {
   const platforms = ["linkedin", "twitter", "facebook", "instagram"];
   const profiles: Record<string, string | undefined> = {};

   for (const platform of platforms) {
      const results = await services.web.search({
         query: `${companyName}`,
         domain: `${platform}.com`,
      });

      if (results.results.length > 0) {
         profiles[platform] = results.results[0].link;
      }
   }

   return profiles;
}

const profiles = await findSocialProfiles("Stripe");
console.log(profiles);
// {
//   linkedin: "https://linkedin.com/company/stripe",
//   twitter: "https://twitter.com/stripe",
//   ...
// }

Best Practices

Never use the site: operator: Instead of query: "site:example.com pricing", use query: "pricing", domain: "example.com"
Knowledge Graph: The knowledge graph is only available for well-known entities (companies, people, places). Check if it exists before accessing its properties.
Result Limits: Search results are limited to prevent overwhelming responses. Results are ranked by relevance, so the most useful information is typically in the first few results.

Advanced Patterns

async function searchMultipleDomains(query: string, domains: string[]) {
   const results = await Promise.all(domains.map((domain) => services.web.search({ query, domain })));

   return domains.map((domain, i) => ({
      domain,
      results: results[i].results,
   }));
}

const comparison = await searchMultipleDomains("pricing", ["stripe.com", "square.com", "paypal.com"]);

Search Result Validation

async function findAndValidate(query: string, domain: string) {
   const results = await services.web.search({ query, domain });

   if (results.results.length === 0) {
      return { found: false, url: null };
   }

   const topResult = results.results[0];

   // Validate the result is actually from the domain
   const isValid = topResult.link.includes(domain);

   return {
      found: true,
      url: topResult.link,
      title: topResult.title,
      valid: isValid,
   };
}

Error Handling

async function searchSafely(query: string) {
   try {
      const results = await services.web.search({ query });

      if (!results.results || results.results.length === 0) {
         console.log("No results found");
         return null;
      }

      return results;
   } catch (error) {
      console.error("Search failed:", error);
      return null;
   }
}