# Google AI Overview

> A full recreation of Google's AI Overview built from the AI Overview components on shadcn Base UI.

A shadcn/ui block from the [@notra](https://ui.usenotra.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/notra/google-ai-overview).

- Page, with a live preview: https://shadcn.exchange/r/notra/google-ai-overview
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/notra/google-ai-overview-light-e9f75dffb9472ad0.png
- Registry item: https://ui.usenotra.com/r/google-ai-overview.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://ui.usenotra.com/r/google-ai-overview.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `cn`, `sonner`
- Registry items: `avatar`, `badge`, `button`, `collapsible`, `hover-card`, `separator`, `skeleton`, `sonner`

## Files

### `registry/notra/google-ai-overview/components/ai-overview.tsx`

```tsx
"use client";

import { cn } from "cn";

import { Button } from "@/components/ui/button";
import { Collapsible, CollapsibleTrigger } from "@/components/ui/collapsible";

import type { AIOverviewProps } from "../types/google-ai-overview";
import { AIOverviewChevronIcon } from "./ai-overview-icons";

export const AIOverview = ({
  children,
  className,
  collapsible = true,
  open,
  render = <section />,
  showMoreLabel = "Show more",
  ...props
}: AIOverviewProps) => (
  <Collapsible
    className={cn(
      "group/ai-overview bg-aio-bg font-aio text-aio-fg relative text-base leading-6 font-normal antialiased",
      collapsible &&
        "data-closed:max-h-[var(--aio-collapsed-height,36.4375rem)] data-closed:overflow-y-clip",
      className
    )}
    data-slot="ai-overview"
    open={collapsible ? open : true}
    render={render}
    {...props}
  >
    {children}
    {collapsible && (
      <>
        <div
          aria-hidden="true"
          className="pointer-events-none absolute inset-x-0 bottom-0 z-2 h-37 bg-[linear-gradient(transparent_0,color-mix(in_srgb,var(--aio-bg)_90%,transparent)_3.25rem,var(--aio-bg)_5rem)] group-data-open/ai-overview:hidden"
        />
        <div className="bg-aio-bg absolute inset-x-0 bottom-5 z-2 pb-0.5 group-data-open/ai-overview:hidden">
          <CollapsibleTrigger
            render={
              <Button
                className="border-aio-button-border text-aio-button-fg hover:bg-aio-button-icon/[8.24%] hover:text-aio-button-fg focus-visible:border-aio-button-border focus-visible:outline-aio-focus active:bg-aio-button-icon/[22.4%] dark:border-aio-button-border dark:hover:bg-aio-button-icon/[8.24%] dark:active:bg-aio-button-icon/[22.4%] h-12.5 w-full max-w-177 gap-0 rounded-full bg-transparent px-[0.9375rem] py-[0.6875rem] text-sm leading-5 font-medium shadow-none transition-none [corner-shape:round] focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-solid active:not-aria-[haspopup]:translate-y-0 supports-[corner-shape:squircle]:rounded-full dark:bg-transparent"
                variant="outline"
              />
            }
          >
            {showMoreLabel}
            <AIOverviewChevronIcon className="text-aio-button-icon ml-2 size-5" />
          </CollapsibleTrigger>
        </div>
      </>
    )}
  </Collapsible>
);
```

### `registry/notra/google-ai-overview/components/ai-overview-icons.tsx`

```tsx
import type { ComponentProps } from "react";

export const AIOverviewSparkleIcon = (props: ComponentProps<"svg">) => (
  <svg aria-hidden="true" viewBox="0 0 471 471" {...props}>
    <path
      d="M235.5 471C235.5 438.423 229.22 407.807 216.66 379.155C204.492 350.503 187.811 325.579 166.616 304.384C145.421 283.189 120.498 266.508 91.845 254.34C63.1925 241.78 32.5775 235.5 0 235.5C32.5775 235.5 63.1925 229.416 91.845 217.249C120.498 204.689 145.421 187.811 166.616 166.616C187.811 145.421 204.492 120.497 216.66 91.845C229.22 63.1925 235.5 32.5775 235.5 0C235.5 32.5775 241.584 63.1925 253.751 91.845C266.311 120.497 283.189 145.421 304.384 166.616C325.579 187.811 350.503 204.689 379.155 217.249C407.807 229.416 438.423 235.5 471 235.5C438.423 235.5 407.807 241.78 379.155 254.34C350.503 266.508 325.579 283.189 304.384 304.384C283.189 325.579 266.311 350.503 253.751 379.155C241.584 407.807 235.5 438.423 235.5 471Z"
      fill="currentColor"
    />
  </svg>
);

export const AIOverviewChevronIcon = (props: ComponentProps<"svg">) => (
  <svg aria-hidden="true" fill="currentColor" viewBox="0 0 24 24" {...props}>
    <path d="M5.41 7.59L4 9l8 8 8-8-1.41-1.41L12 14.17" />
  </svg>
);

export const AIOverviewMoreIcon = (props: ComponentProps<"svg">) => (
  <svg aria-hidden="true" fill="currentColor" viewBox="0 0 24 24" {...props}>
    <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
  </svg>
);
```

### `registry/notra/google-ai-overview/types/google-ai-overview.ts`

```ts
import type { ComponentProps, ReactNode } from "react";

import type { Avatar } from "@/components/ui/avatar";
import type { Collapsible } from "@/components/ui/collapsible";

export interface AIOverviewSource {
  description?: string;
  favicon: string;
  href: string;
  meta?: string;
  siteName: string;
  thumbnail?: string;
  title?: string;
}

export interface AIOverviewProps extends ComponentProps<typeof Collapsible> {
  collapsible?: boolean;
  showMoreLabel?: ReactNode;
}

export interface AIOverviewHeaderProps extends Omit<
  ComponentProps<"div">,
  "title"
> {
  icon?: ReactNode;
  title?: ReactNode;
}

export interface AIOverviewHighlightProps extends ComponentProps<"mark"> {
  active?: boolean;
}

export interface AIOverviewCitationProps extends Omit<
  ComponentProps<"a">,
  "href" | "children"
> {
  preview?: boolean;
  renderSourceAction?: (source: AIOverviewSource) => ReactNode;
  sources: [AIOverviewSource, ...AIOverviewSource[]];
}

export interface AIOverviewFaviconProps extends ComponentProps<typeof Avatar> {
  name: string;
  src: string;
}

export interface AIOverviewSkeletonLine {
  id: string;
  width: string;
}

export interface AIOverviewSkeletonProps extends ComponentProps<"div"> {
  lines?: AIOverviewSkeletonLine[];
}
```

### `registry/notra/google-ai-overview/components/ai-overview-header.tsx`

```tsx
import { cn } from "cn";

import type { AIOverviewHeaderProps } from "../types/google-ai-overview";
import { AIOverviewSparkleIcon } from "./ai-overview-icons";

export const AIOverviewHeader = ({
  children,
  className,
  icon = <AIOverviewSparkleIcon className="size-6 shrink-0" />,
  title = "AI Overview",
  ...props
}: AIOverviewHeaderProps) => (
  <div
    className={cn("flex items-center justify-between gap-4 pb-4", className)}
    data-slot="ai-overview-header"
    {...props}
  >
    <div className="text-aio-sparkle flex items-center gap-1.5">
      {icon}
      <h2 className="text-aio-label text-sm font-medium">{title}</h2>
    </div>
    {children}
  </div>
);
```

### `registry/notra/google-ai-overview/components/ai-overview-content.tsx`

```tsx
import { cn } from "cn";
import type { ComponentProps } from "react";

export const AIOverviewContent = ({
  className,
  ...props
}: ComponentProps<"div">) => (
  <div
    className={cn("max-w-177 wrap-break-word", className)}
    data-slot="ai-overview-content"
    {...props}
  />
);

export const AIOverviewParagraph = ({
  className,
  ...props
}: ComponentProps<"p">) => (
  <p
    className={cn("mb-4 last:mb-0", className)}
    data-slot="ai-overview-paragraph"
    {...props}
  />
);

export const AIOverviewHeading = ({
  children,
  className,
  ...props
}: ComponentProps<"h3">) => (
  <h3
    className={cn(
      "text-aio-heading mt-6 mb-3 text-xl leading-7 font-semibold tracking-normal first:mt-0",
      className
    )}
    data-slot="ai-overview-heading"
    {...props}
  >
    {children}
  </h3>
);

export const AIOverviewList = ({
  className,
  ...props
}: ComponentProps<"ul">) => (
  <ul
    className={cn("mt-3 mb-4 list-disc ps-4.5 [&_ul]:list-[circle]", className)}
    data-slot="ai-overview-list"
    {...props}
  />
);

export const AIOverviewListItem = ({
  className,
  ...props
}: ComponentProps<"li">) => (
  <li
    className={cn("mb-3 ps-1", className)}
    data-slot="ai-overview-list-item"
    {...props}
  />
);

export const AIOverviewLink = ({
  children,
  className,
  rel = "noopener noreferrer",
  target = "_blank",
  ...props
}: ComponentProps<"a">) => (
  <a
    className={cn(
      "text-aio-link decoration-aio-link font-medium underline decoration-1 underline-offset-[0.0625rem]",
      className
    )}
    data-slot="ai-overview-link"
    rel={rel}
    target={target}
    {...props}
  >
    {children}
  </a>
);
```

### `registry/notra/google-ai-overview/components/ai-overview-highlight.tsx`

```tsx
import { cn } from "cn";

import type { AIOverviewHighlightProps } from "../types/google-ai-overview";

export const AIOverviewHighlight = ({
  active = false,
  className,
  ...props
}: AIOverviewHighlightProps) => (
  <mark
    className={cn(
      "rounded-sm bg-transparent bg-[linear-gradient(90deg,var(--aio-mark)_50%,transparent_50%)] bg-size-[200%_100%] bg-position-[100%_0] px-0.5 text-inherit transition-[background-position] duration-750 ease-[cubic-bezier(0.05,0.7,0.1,1)] motion-reduce:transition-none",
      "[&:has(+[data-slot=ai-overview-citation]:is(:hover,:focus-within))]:bg-aio-hover [&:has(+[data-slot=ai-overview-citation]:is(:hover,:focus-within))]:rounded-none [&:has(+[data-slot=ai-overview-citation]:is(:hover,:focus-within))]:bg-none",
      active &&
        "text-aio-mark-fg bg-position-[0_0] font-medium delay-250 starting:bg-position-[100%_0]",
      className
    )}
    data-active={active || undefined}
    data-slot="ai-overview-highlight"
    {...props}
  />
);
```

### `registry/notra/google-ai-overview/components/ai-overview-citation.tsx`

```tsx
import { cn } from "cn";

import { Badge, badgeVariants } from "@/components/ui/badge";
import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@/components/ui/hover-card";
import { Separator } from "@/components/ui/separator";

import {
  AI_OVERVIEW_HOVER_CLOSE_DELAY_MS,
  AI_OVERVIEW_HOVER_OPEN_DELAY_MS,
} from "../constants/google-ai-overview";
import type {
  AIOverviewCitationProps,
  AIOverviewSource,
} from "../types/google-ai-overview";
import { AIOverviewFavicon } from "./ai-overview-favicon";

const sourceLabel = (source: AIOverviewSource) =>
  source.meta ? `${source.siteName} · ${source.meta}` : source.siteName;

export const AIOverviewCitation = ({
  className,
  preview = true,
  rel = "noopener noreferrer",
  renderSourceAction,
  sources,
  target = "_blank",
  ...props
}: AIOverviewCitationProps) => {
  const [source] = sources;
  const label = sourceLabel(source);
  const extra = sources.length - 1;
  const chipClassName = cn(
    badgeVariants({ variant: "secondary" }),
    "bg-aio-chip text-aio-muted focus-visible:outline-aio-focus [a]:hover:bg-aio-chip-hover max-w-[10.9375rem] justify-start rounded-full border-0 py-px ps-px pe-2 align-text-top text-[0.6875rem] leading-4 focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-solid",
    className
  );
  const chip = (
    <>
      <AIOverviewFavicon name={source.siteName} src={source.favicon} />
      <span className="truncate">{label}</span>
      {extra > 0 && <span className="-ms-1 shrink-0">&nbsp;+{extra}</span>}
    </>
  );
  const ariaLabel = extra > 0 ? `${label} (+${extra})` : label;

  return (
    <span className="whitespace-nowrap" data-slot="ai-overview-citation">
      <span aria-hidden="true">&nbsp;</span>
      {preview ? (
        <HoverCard>
          <HoverCardTrigger
            aria-label={ariaLabel}
            closeDelay={AI_OVERVIEW_HOVER_CLOSE_DELAY_MS}
            delay={AI_OVERVIEW_HOVER_OPEN_DELAY_MS}
            className={chipClassName}
            href={source.href}
            rel={rel}
            target={target}
            {...props}
          >
            {chip}
          </HoverCardTrigger>
          <HoverCardContent
            align="start"
            alignOffset={-10}
            className="bg-aio-popover font-aio text-aio-popover-fg max-h-72.5 w-90 overflow-y-auto rounded-[1.25rem] p-0 antialiased shadow-[0_1px_2px_0_rgb(0_0_0/0.3),0_2px_6px_2px_rgb(0_0_0/0.15)] ring-0"
            sideOffset={8}
          >
            <ul>
              {sources.map((item, index) => (
                <li
                  className="after:bg-aio-border relative after:absolute after:inset-x-4 after:bottom-0 after:h-px last:after:hidden"
                  key={item.href}
                >
                  {index > 0 && (
                    <Separator className="bg-aio-border mx-4 data-horizontal:w-auto" />
                  )}
                  <a
                    aria-label={item.title ?? item.siteName}
                    className="focus-visible:outline-aio-focus absolute inset-0.5 rounded-2xl focus-visible:outline-2 focus-visible:outline-solid"
                    href={item.href}
                    rel={rel}
                    target={target}
                  />
                  <div className="pointer-events-none flex flex-col gap-2 p-3">
                    <div className="text-aio-popover-muted flex h-4.5 min-w-0 items-center pe-6 text-xs leading-4">
                      <AIOverviewFavicon
                        name={item.siteName}
                        src={item.favicon}
                      />
                      <span className="ms-[0.3125rem] truncate">
                        {item.siteName}
                      </span>
                      {item.meta && (
                        <>
                          <span className="mx-1.5">·</span>
                          <span className="truncate text-[0.6875rem]">
                            {item.meta}
                          </span>
                        </>
                      )}
                    </div>
                    <div className="flex gap-2">
                      <div className="flex min-w-0 flex-1 flex-col gap-1 pe-3">
                        <span className="line-clamp-2 text-sm leading-4.5 font-medium">
                          {item.title ?? item.siteName}
                        </span>
                        {item.description && (
                          <span className="text-aio-popover-muted line-clamp-2 text-xs leading-4">
                            {item.description}
                          </span>
                        )}
                      </div>
                      {item.thumbnail && (
                        <img
                          alt=""
                          className="size-17 shrink-0 rounded-lg object-cover"
                          src={item.thumbnail}
                        />
                      )}
                    </div>
                  </div>
                  {renderSourceAction && (
                    <div className="absolute end-0.75 top-0.75">
                      {renderSourceAction(item)}
                    </div>
                  )}
                </li>
              ))}
            </ul>
          </HoverCardContent>
        </HoverCard>
      ) : (
        <Badge
          className={chipClassName}
          render={
            <a
              aria-label={ariaLabel}
              href={source.href}
              rel={rel}
              target={target}
              {...props}
            />
          }
          variant="secondary"
        >
          {chip}
        </Badge>
      )}
    </span>
  );
};
```

### `registry/notra/google-ai-overview/components/ai-overview-favicon.tsx`

```tsx
import { cn } from "cn";

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";

import type { AIOverviewFaviconProps } from "../types/google-ai-overview";

export const AIOverviewFavicon = ({
  className,
  name,
  src,
  ...props
}: AIOverviewFaviconProps) => (
  <Avatar
    className={cn(
      "after:border-aio-border size-4.5 bg-white after:mix-blend-normal dark:after:mix-blend-normal",
      className
    )}
    data-slot="ai-overview-favicon"
    {...props}
  >
    <AvatarImage alt="" className="object-contain p-0.5" src={src} />
    <AvatarFallback className="text-aio-muted bg-white text-[0.5rem] font-medium">
      {Array.from(name)[0]}
    </AvatarFallback>
  </Avatar>
);
```

### `registry/notra/google-ai-overview/components/ai-overview-skeleton.tsx`

```tsx
import { cn } from "cn";

import { Skeleton } from "@/components/ui/skeleton";

import { AI_OVERVIEW_SKELETON_LINES } from "../constants/google-ai-overview";
import type { AIOverviewSkeletonProps } from "../types/google-ai-overview";

export const AIOverviewSkeleton = ({
  className,
  lines = AI_OVERVIEW_SKELETON_LINES,
  ...props
}: AIOverviewSkeletonProps) => (
  <div
    aria-busy="true"
    className={cn("flex max-w-177 flex-col gap-3", className)}
    data-slot="ai-overview-skeleton"
    {...props}
  >
    {lines.map((line) => (
      <Skeleton
        className="bg-aio-chip h-4 rounded-full"
        key={line.id}
        style={{ width: line.width }}
      />
    ))}
  </div>
);
```

### `registry/notra/google-ai-overview/constants/google-ai-overview.ts`

```ts
import type { AIOverviewSkeletonLine } from "../types/google-ai-overview";

export const AI_OVERVIEW_SKELETON_LINES: AIOverviewSkeletonLine[] = [
  { id: "line-1", width: "100%" },
  { id: "line-2", width: "94%" },
  { id: "line-3", width: "97%" },
  { id: "line-4", width: "62%" },
];

export const AI_OVERVIEW_HOVER_OPEN_DELAY_MS = 150;

export const AI_OVERVIEW_HOVER_CLOSE_DELAY_MS = 100;
```

### `registry/notra/google-ai-overview/constants/vercel-sources.ts`

```ts
import type { AIOverviewSource } from "../types/google-ai-overview";

export const VERCEL = {
  favicon: "/google-ai-overview/vercel.svg",
  href: "https://vercel.com/blog/what-is-vercel",
  siteName: "Vercel",
  description:
    '"Technically" newsletter founder Justin Gage explains how Vercel makes building web applications as easy as possible.',
  title: "What does Vercel do?",
} satisfies AIOverviewSource;

export const VERCEL_DOCS = {
  favicon: "/google-ai-overview/vercel.svg",
  href: "https://vercel.com/docs",
  siteName: "Vercel",
  description:
    "Vercel is the AI Cloud, a unified platform for building, deploying, and scaling AI-powered applications.",
  title: "Vercel Documentation",
} satisfies AIOverviewSource;

export const YOUTUBE_VERCEL = {
  favicon: "/google-ai-overview/youtube.svg",
  href: "https://www.youtube.com/@VercelHQ",
  meta: "Vercel",
  siteName: "YouTube",
  description:
    "Vercel Product Walkthrough hey I'm Lee and I'll be your guide in this video as we do a walkthrough of the platform.",
  title: "Vercel Product Walkthrough",
} satisfies AIOverviewSource;

export const GITHUB_VERCEL = {
  favicon: "/google-ai-overview/github.svg",
  href: "https://github.com/vercel",
  siteName: "GitHub",
  thumbnail: "https://opengraph.githubassets.com/1/vercel/vercel",
  description:
    "Develop. Preview. Ship. Creators of Next.js, the React framework.",
  title: "Vercel on GitHub",
} satisfies AIOverviewSource;

export const NEXTJS = {
  favicon: "/google-ai-overview/nextjs.svg",
  href: "https://nextjs.org",
  siteName: "nextjs.org",
  thumbnail: "https://opengraph.githubassets.com/1/vercel/next.js",
  description:
    "Used by some of the world's largest companies, Next.js enables you to create high-quality web applications.",
  title: "Next.js by Vercel: The React Framework",
} satisfies AIOverviewSource;
```

### `registry/notra/google-ai-overview/components/ai-overview-source-action.tsx`

```tsx
import { cn } from "cn";
import type { ComponentProps } from "react";

import { Button } from "@/components/ui/button";

import { AIOverviewMoreIcon } from "./ai-overview-icons";

export const AIOverviewSourceAction = ({
  "aria-label": ariaLabel = "About this result",
  className,
  ...props
}: ComponentProps<typeof Button>) => (
  <Button
    aria-label={ariaLabel}
    className={cn(
      "text-aio-action hover:bg-aio-action/8 hover:text-aio-action dark:hover:bg-aio-action/8 focus-visible:outline-aio-focus active:bg-aio-action/22 size-9 rounded-full p-2.25 focus-visible:border-transparent focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-solid active:not-aria-[haspopup]:translate-y-0",
      className
    )}
    data-slot="ai-overview-source-action"
    size="icon"
    variant="ghost"
    {...props}
  >
    <AIOverviewMoreIcon className="size-4.5" />
  </Button>
);
```

### `registry/notra/google-ai-overview/examples/google-ai-overview-demo.tsx`

```tsx
"use client";

import { toast } from "sonner";

import { AIOverview } from "../components/ai-overview";
import { AIOverviewCitation } from "../components/ai-overview-citation";
import {
  AIOverviewContent,
  AIOverviewHeading,
  AIOverviewLink,
  AIOverviewList,
  AIOverviewListItem,
  AIOverviewParagraph,
} from "../components/ai-overview-content";
import { AIOverviewHeader } from "../components/ai-overview-header";
import { AIOverviewHighlight } from "../components/ai-overview-highlight";
import { AIOverviewSourceAction } from "../components/ai-overview-source-action";
import {
  GITHUB_VERCEL,
  NEXTJS,
  VERCEL,
  VERCEL_DOCS,
  YOUTUBE_VERCEL,
} from "../constants/vercel-sources";
import type { AIOverviewSource } from "../types/google-ai-overview";

const renderSourceAction = (source: AIOverviewSource) => (
  <AIOverviewSourceAction
    onClick={() => toast("3 dot button clicked", { description: source.title })}
  />
);

export default function GoogleAIOverviewDemo() {
  return (
    <AIOverview className="p-6">
      <AIOverviewHeader />
      <AIOverviewContent>
        <AIOverviewParagraph>
          <AIOverviewLink href="https://vercel.com">Vercel</AIOverviewLink> is{" "}
          <AIOverviewHighlight active>
            a cloud platform that helps developers build, deploy, and host fast
            modern websites and web applications
          </AIOverviewHighlight>
          .
          <AIOverviewCitation
            renderSourceAction={renderSourceAction}
            sources={[VERCEL, VERCEL_DOCS]}
          />
        </AIOverviewParagraph>
        <AIOverviewHeading>What Vercel Does</AIOverviewHeading>
        <AIOverviewList>
          <AIOverviewListItem>
            <strong>Easy Hosting:</strong>{" "}
            <AIOverviewHighlight>
              It handles the servers and infrastructure so you can launch
              user-facing websites quickly.
            </AIOverviewHighlight>
            <AIOverviewCitation
              renderSourceAction={renderSourceAction}
              sources={[VERCEL, VERCEL_DOCS]}
            />
          </AIOverviewListItem>
          <AIOverviewListItem>
            <strong>Git Integration:</strong>{" "}
            <AIOverviewHighlight>
              It connects to GitHub, GitLab, or Bitbucket and deploys a live
              version of your site every time you push changes.
            </AIOverviewHighlight>
            <AIOverviewCitation
              renderSourceAction={renderSourceAction}
              sources={[YOUTUBE_VERCEL, GITHUB_VERCEL, VERCEL_DOCS]}
            />
          </AIOverviewListItem>
          <AIOverviewListItem>
            <strong>Preview Links:</strong>{" "}
            <AIOverviewHighlight>
              Every pull request gets a unique preview URL so teams can review
              work before it goes public.
            </AIOverviewHighlight>
            <AIOverviewCitation
              renderSourceAction={renderSourceAction}
              sources={[GITHUB_VERCEL, VERCEL_DOCS]}
            />
          </AIOverviewListItem>
          <AIOverviewListItem>
            <strong>Global Speed:</strong>{" "}
            <AIOverviewHighlight>
              A global CDN serves your site from servers close to your users.
            </AIOverviewHighlight>
            <AIOverviewCitation
              renderSourceAction={renderSourceAction}
              sources={[VERCEL_DOCS]}
            />
          </AIOverviewListItem>
        </AIOverviewList>
        <AIOverviewHeading>Key Features</AIOverviewHeading>
        <AIOverviewList>
          <AIOverviewListItem>
            <strong>Framework Support:</strong> It supports React, Vue, Svelte,
            and Astro, and is the creator and primary host of Next.js.
            <AIOverviewCitation
              renderSourceAction={renderSourceAction}
              sources={[NEXTJS, VERCEL]}
            />
          </AIOverviewListItem>
          <AIOverviewListItem>
            <strong>Serverless Functions:</strong> It runs backend code tied to
            HTTP requests without a full-time server.
          </AIOverviewListItem>
          <AIOverviewListItem>
            <strong>AI Tools:</strong> It makes v0, which generates website code
            from text prompts.
            <AIOverviewCitation
              renderSourceAction={renderSourceAction}
              sources={[VERCEL, NEXTJS, YOUTUBE_VERCEL]}
            />
          </AIOverviewListItem>
        </AIOverviewList>
      </AIOverviewContent>
    </AIOverview>
  );
}
```

### `public/google-ai-overview/vercel.svg`

```svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 222" preserveAspectRatio="xMidYMid"><path d="m128 0 128 221.705H0z"/></svg>
```

### `public/google-ai-overview/github.svg`

```svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="none"><path fill="#1b1f23" fill-rule="evenodd" d="M512 0C229.12 0 0 229.12 0 512c0 226.56 146.56 417.92 350.08 485.76 25.6 4.48 35.2-10.88 35.2-24.32 0-12.16-.64-52.48-.64-95.36-128.64 23.68-161.92-31.36-172.16-60.16-5.76-14.72-30.72-60.16-52.48-72.32-17.92-9.6-43.52-33.28-.64-33.92 40.32-.64 69.12 37.12 78.72 52.48 46.08 77.44 119.68 55.68 149.12 42.24 4.48-33.28 17.92-55.68 32.64-68.48-113.92-12.8-232.96-56.96-232.96-252.8 0-55.68 19.84-101.76 52.48-137.6-5.12-12.8-23.04-65.28 5.12-135.68 0 0 42.88-13.44 140.8 52.48 40.96-11.52 84.48-17.28 128-17.28s87.04 5.76 128 17.28c97.92-66.56 140.8-52.48 140.8-52.48 28.16 70.4 10.24 122.88 5.12 135.68 32.64 35.84 52.48 81.28 52.48 137.6 0 196.48-119.68 240-233.6 252.8 18.56 16 34.56 46.72 34.56 94.72 0 68.48-.64 123.52-.64 140.8 0 13.44 9.6 29.44 35.2 24.32C877.44 929.92 1024 737.92 1024 512 1024 229.12 794.88 0 512 0" clip-rule="evenodd"/></svg>
```

### `public/google-ai-overview/youtube.svg`

```svg
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 180"><path fill="red" d="M250.346 28.075A32.18 32.18 0 0 0 227.69 5.418C207.824 0 127.87 0 127.87 0S47.912.164 28.046 5.582A32.18 32.18 0 0 0 5.39 28.24c-6.009 35.298-8.34 89.084.165 122.97a32.18 32.18 0 0 0 22.656 22.657c19.866 5.418 99.822 5.418 99.822 5.418s79.955 0 99.82-5.418a32.18 32.18 0 0 0 22.657-22.657c6.338-35.348 8.291-89.1-.164-123.134Z"/><path fill="#FFF" d="m102.421 128.06 66.328-38.418-66.328-38.418z"/></svg>
```

### `public/google-ai-overview/nextjs.svg`

```svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180"><mask height="180" id=":r8:mask0_408_134" maskUnits="userSpaceOnUse" width="180" x="0" y="0" style="mask-type:alpha"><circle cx="90" cy="90" fill="black" r="90"/></mask><g mask="url(#:r8:mask0_408_134)"><circle cx="90" cy="90" data-circle="true" fill="black" r="90"/><path d="M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.845C143.333 162.614 146.509 160.165 149.508 157.52Z" fill="url(#:r8:paint0_linear_408_134)"/><rect fill="url(#:r8:paint1_linear_408_134)" height="72" width="12" x="115" y="54"/></g><defs><linearGradient gradientUnits="userSpaceOnUse" id=":r8:paint0_linear_408_134" x1="109" x2="144.5" y1="116.5" y2="160.5"><stop stop-color="white"/><stop offset="1" stop-color="white" stop-opacity="0"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id=":r8:paint1_linear_408_134" x1="121" x2="120.799" y1="54" y2="106.875"><stop stop-color="white"/><stop offset="1" stop-color="white" stop-opacity="0"/></linearGradient></defs></svg>
```
