> ## Documentation Index
> Fetch the complete documentation index at: https://discord-markm-docs-lobby-membership-disconnect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrating the Discord Social SDK

> Learn how to integrate Discord-powered social features into your game.

export const BrowserIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" fill-rule="evenodd" d="M1 6a3 3 0 0 1 3-3h16a3 3 0 0 1 3 3v2a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6Zm3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm4-1a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm2 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" clip-rule="evenodd" /><path fill="currentColor" d="M1 12a1 1 0 0 1 1-1h20a1 1 0 0 1 1 1v6a3 3 0 0 1-3 3H4a3 3 0 0 1-3-3v-6Z" /></svg>;

export const PaintPaletteIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" fill-rule="evenodd" d="M19 16h-5a2 2 0 0 0-2 2v2c0 1.66-1.37 3.04-2.96 2.6A11 11 0 1 1 23 12c0 2.2-2 4-4 4ZM13.5 4.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM17.25 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm-9-1.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm-3.75 7a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd" /></svg>;

export const WrenchIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" d="M7.8 15.77c.7.43 1.2 1.14 1.2 1.96V21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-3.27c0-.82.5-1.53 1.2-1.96a8.06 8.06 0 0 0 .12-13.63c-.6-.39-1.32.09-1.32.8v5.98a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V2.94c0-.71-.72-1.19-1.32-.8a8.06 8.06 0 0 0 .12 13.63Z" /></svg>;

export const YouTubeEmbed = ({src, title = "YouTube video player", showDuration = false, chapters = ""}) => {
  const iframeRef = useRef(null);
  const detailsRef = useRef(null);
  const [duration, setDuration] = useState(null);
  const [activeChapter, setActiveChapter] = useState(-1);
  const formatDuration = seconds => {
    const h = Math.floor(seconds / 3600);
    const m = Math.floor(seconds % 3600 / 60);
    const s = Math.round(seconds % 60);
    const pad = n => String(n).padStart(2, "0");
    return h > 0 ? `${h}:${pad(m)}:${pad(s)}` : `${m}:${pad(s)}`;
  };
  const parsedChapters = useMemo(() => {
    if (!chapters) return [];
    return chapters.split("\n").map(line => {
      const match = line.match(/^\s*[-*•]?\s*(?:(\d+):)?(\d{1,2}):(\d{2})\s*[-–—:]?\s*(\S.*)$/);
      if (!match) return null;
      const [, h, m, s, chapterTitle] = match;
      const seconds = (h ? parseInt(h, 10) * 3600 : 0) + parseInt(m, 10) * 60 + parseInt(s, 10);
      return {
        seconds,
        label: formatDuration(seconds),
        title: chapterTitle.trim()
      };
    }).filter(Boolean);
  }, [chapters]);
  const jsApiEnabled = showDuration || parsedChapters.length > 0;
  useEffect(() => {
    if (parsedChapters.length === 0) return;
    const onPointerDown = event => {
      const details = detailsRef.current;
      if (details?.open && !details.contains(event.target)) details.open = false;
    };
    document.addEventListener("pointerdown", onPointerDown);
    return () => document.removeEventListener("pointerdown", onPointerDown);
  }, [parsedChapters.length]);
  useEffect(() => {
    if (!jsApiEnabled) return;
    const onMessage = event => {
      if (event.origin !== "https://www.youtube.com") return;
      if (!iframeRef.current || event.source !== iframeRef.current.contentWindow) return;
      let data;
      try {
        data = JSON.parse(event.data);
      } catch {
        return;
      }
      const seconds = data?.info?.duration;
      if (typeof seconds === "number" && seconds > 0) setDuration(seconds);
      const currentTime = data?.info?.currentTime;
      if (typeof currentTime === "number" && parsedChapters.length > 0) {
        let index = -1;
        for (let i = 0; i < parsedChapters.length; i++) {
          if (parsedChapters[i].seconds <= currentTime) index = i;
        }
        setActiveChapter(index);
      }
    };
    window.addEventListener("message", onMessage);
    return () => window.removeEventListener("message", onMessage);
  }, [jsApiEnabled, parsedChapters]);
  const postToPlayer = payload => {
    iframeRef.current?.contentWindow?.postMessage(JSON.stringify(payload), "https://www.youtube.com");
  };
  const handleLoad = () => {
    postToPlayer({
      event: "listening",
      id: "ytembed",
      channel: "widget"
    });
  };
  const seekTo = seconds => {
    postToPlayer({
      event: "command",
      func: "seekTo",
      args: [seconds, true]
    });
    postToPlayer({
      event: "command",
      func: "playVideo",
      args: []
    });
  };
  const embedSrc = jsApiEnabled ? `${src}${src.includes("?") ? "&" : "?"}enablejsapi=1` : src;
  return <div>
      <iframe ref={iframeRef} className="w-full aspect-video rounded-xl" src={embedSrc} title={title} frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerPolicy="strict-origin-when-cross-origin" allowFullScreen onLoad={jsApiEnabled ? handleLoad : undefined}></iframe>
      {(showDuration || parsedChapters.length > 0) && <div className="relative mt-2 flex items-start justify-between gap-4 text-sm text-gray-500 dark:text-zinc-500">
          {parsedChapters.length > 0 && <details ref={detailsRef}>
              <summary className="cursor-pointer select-none">Chapters</summary>
              <ul className="absolute left-0 top-full z-10 mt-1 mb-0 max-h-72 w-max max-w-full list-none overflow-y-auto rounded-xl border border-gray-200 bg-white p-3 pl-3 shadow-lg dark:border-zinc-700 dark:bg-zinc-800">
                {parsedChapters.map((chapter, index) => <li key={chapter.seconds} className="m-0 pl-0">
                    <button type="button" className={`cursor-pointer rounded-md px-1.5 py-0.5 text-left hover:text-gray-700 dark:hover:text-zinc-300 ${index === activeChapter ? "bg-gray-100 text-gray-800 dark:bg-zinc-700 dark:text-zinc-200" : ""}`} onClick={() => {
    seekTo(chapter.seconds);
    if (detailsRef.current) detailsRef.current.open = false;
  }}>
                      <span className="font-medium text-primary dark:text-primary-light">
                        {chapter.label}
                      </span>{" "}
                      {chapter.title}
                    </button>
                  </li>)}
              </ul>
            </details>}
          {showDuration && duration !== null && <p className="m-0 ml-auto">Duration: {formatDuration(duration)}</p>}
        </div>}
    </div>;
};

export const CompassIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" d="M12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z" /><path fill="currentColor" fill-rule="evenodd" d="M23 12a11 11 0 1 1-22 0 11 11 0 0 1 22 0ZM7.74 9.3A2 2 0 0 1 9.3 7.75l7.22-1.45a1 1 0 0 1 1.18 1.18l-1.45 7.22a2 2 0 0 1-1.57 1.57l-7.22 1.45a1 1 0 0 1-1.18-1.18L7.74 9.3Z" clip-rule="evenodd" /></svg>;

export const GameControllerIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" fill-rule="evenodd" d="M20.97 4.06c0 .18.08.35.24.43.55.28.9.82 1.04 1.42.3 1.24.75 3.7.75 7.09v4.91a3.09 3.09 0 0 1-5.85 1.38l-1.76-3.51a1.09 1.09 0 0 0-1.23-.55c-.57.13-1.36.27-2.16.27s-1.6-.14-2.16-.27c-.49-.11-1 .1-1.23.55l-1.76 3.51A3.09 3.09 0 0 1 1 17.91V13c0-3.38.46-5.85.75-7.1.15-.6.49-1.13 1.04-1.4a.47.47 0 0 0 .24-.44c0-.7.48-1.32 1.2-1.47l2.93-.62c.5-.1 1 .06 1.36.4.35.34.78.71 1.28.68a42.4 42.4 0 0 1 4.4 0c.5.03.93-.34 1.28-.69.35-.33.86-.5 1.36-.39l2.94.62c.7.15 1.19.78 1.19 1.47ZM20 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM15.5 12a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM5 7a1 1 0 0 1 2 0v1h1a1 1 0 0 1 0 2H7v1a1 1 0 1 1-2 0v-1H4a1 1 0 1 1 0-2h1V7Z" clip-rule="evenodd" /></svg>;

<img src="https://mintcdn.com/discord-markm-docs-lobby-membership-disconnect/MXDLwy4pCNDMm72Q/images/headers/docs-sdk-hero.png?fit=max&auto=format&n=MXDLwy4pCNDMm72Q&q=85&s=2f3d5b24976ea6ed9cf8704b12777289" alt="Discord Social SDK Hero Image" style={{width: "100%", height: "auto"}} noZoom width="1336" height="540" data-path="images/headers/docs-sdk-hero.png" />

The Discord Social SDK lets you integrate Discord-powered social features directly into your game. For an overview of available features, see the [Social Layer for Games](/developers/platform/social-layer) platform page.

Start integrating the SDK into your game with our getting started guides, design guidelines, and code samples.

## Integrate Social Features in Your Game

<CardGroup cols={2}>
  <Card title="Core Concepts" href="/developers/discord-social-sdk/core-concepts" icon={<GameControllerIcon />}>
    Learn how the SDK works and explore its key features.
  </Card>

  <Card title="Getting Started Guides" href="/developers/discord-social-sdk/getting-started" icon={<CompassIcon />}>
    Follow our step-by-step guides to add the SDK to your game engine.
  </Card>
</CardGroup>

## Dive Deeper into the Discord Social SDK

<YouTubeEmbed src="https://www.youtube.com/embed/voEc21roLas?si=DBc_jBIJHqMtoDYc" title="Power Player Connections with Discord Social SDK" />

<CardGroup cols={3}>
  <Card title="Development Guides" href="/developers/discord-social-sdk/development-guides" icon={<WrenchIcon />}>
    Dive into feature guides for **account linking, friends lists, game invites, and voice chat**.
  </Card>

  <Card title="Design Guidelines" href="/developers/discord-social-sdk/design-guidelines" icon={<PaintPaletteIcon />}>
    Learn how to design your game's UI to integrate social features.
  </Card>

  <Card title="SDK Reference Docs" href="https://discord.com/developers/docs/social-sdk/index.html" icon={<BrowserIcon />}>
    Explore the SDK's API reference documentation.
  </Card>
</CardGroup>

***

## Communication Features

Discord Social SDK features for text and voice communication are available but capped with rate limits.

For more information about current rate limits for communication features,
please see [Communication Features: Rate Limits](/developers/discord-social-sdk/core-concepts/communication-features#rate-limits).

For more information on how to access these features, please see [Core Concepts: Communication Features](/developers/discord-social-sdk/core-concepts/communication-features).

***

## Get Help & Join the Community

Need support or looking to connect with other game developers?

* Join our [DDevs Discord Server](https://discord.gg/discord-developers) and get help from the community, share best practices, and discover new ways to enhance your game. Find us in the `#social-sdk-dev-help` channel!
* For additional support, you can [file a ticket with Developer Support](https://dis.gd/social-sdk) to report issues.
