> ## Documentation Index
> Fetch the complete documentation index at: https://help.hoopai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Media library

> Learn how to use the centralized media library in the HoopAI Platform to store, organize, and access images, videos, and documents across all your tools.

export const CourseTracker = ({courseId, lessonId, videoId}) => {
  const [progress, setProgress] = useState({});
  const [expanded, setExpanded] = useState(false);
  useEffect(() => {
    setProgress(loadProgress());
    document.body.setAttribute("data-academy", "true");
    return () => document.body.removeAttribute("data-academy");
  }, []);
  const course = COURSES[courseId];
  if (!course) return null;
  const lessons = course.lessons;
  const currentIndex = lessons.findIndex(l => l.id === lessonId);
  const completedCount = lessons.filter(l => !!progress[courseId + "/" + l.id]).length;
  const percent = lessons.length > 0 ? Math.round(completedCount / lessons.length * 100) : 0;
  const isCurrentDone = !!progress[courseId + "/" + lessonId];
  const prev = currentIndex > 0 ? lessons[currentIndex - 1] : null;
  const next = currentIndex < lessons.length - 1 ? lessons[currentIndex + 1] : null;
  const totalDuration = formatTotalDuration(lessons);
  const handleToggle = () => {
    const key = courseId + "/" + lessonId;
    const updated = {
      ...progress
    };
    if (updated[key]) {
      delete updated[key];
    } else {
      updated[key] = Date.now();
    }
    setProgress(updated);
    persistProgress(updated);
  };
  const lessonPath = lesson => "/academy/" + course.dir + "/" + lesson.id;
  const videoEmbed = videoId ? <div style={{
    position: "relative",
    width: "100%",
    paddingBottom: "56.25%",
    borderRadius: "var(--ds-radius-lg)",
    overflow: "hidden",
    marginBottom: "24px",
    background: "#000"
  }}>
      <iframe src={"https://www.youtube-nocookie.com/embed/" + videoId + "?rel=0"} title="Lesson video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen style={{
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    border: "none"
  }} />
    </div> : null;
  const lessonList = lessons.map(lesson => {
    const isActive = lesson.id === lessonId;
    const isDone = !!progress[courseId + "/" + lesson.id];
    const itemStyle = {
      display: "flex",
      alignItems: "center",
      gap: "8px",
      padding: "10px 16px",
      borderTop: "1px solid var(--academy-border-subtle, #f3f4f6)",
      background: isActive ? "var(--academy-active-bg, #f9fafb)" : "transparent",
      textDecoration: "none",
      cursor: isActive ? "default" : "pointer",
      color: "inherit",
      transition: "background 0.15s"
    };
    const titleStyle = {
      flex: 1,
      fontSize: "13px",
      fontWeight: isActive ? 600 : 400,
      color: isActive ? "var(--academy-text, #111827)" : "var(--academy-text-secondary, #6b7280)",
      overflow: "hidden",
      textOverflow: "ellipsis",
      whiteSpace: "nowrap",
      lineHeight: "1.4"
    };
    const durationStyle = {
      fontSize: "12px",
      color: "var(--academy-text-muted, #9ca3af)",
      whiteSpace: "nowrap"
    };
    const inner = <>
        {isDone ? <CheckCircle /> : <VideoIcon />}
        <span style={titleStyle}>{lesson.title}</span>
        <span style={durationStyle}>{lesson.duration}</span>
      </>;
    if (isActive) {
      return <div key={lesson.id} style={itemStyle}>
          {inner}
        </div>;
    }
    return <a key={lesson.id} href={lessonPath(lesson)} style={itemStyle}>
        {inner}
      </a>;
  });
  return <div className="not-prose" id="academy-course-tracker">
      {videoEmbed}
      <div className="academy-tracker" style={{
    fontFamily: "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
    borderRadius: "var(--ds-radius-lg)",
    border: "1px solid var(--academy-border, #e5e7eb)",
    background: "var(--academy-bg, #ffffff)",
    overflow: "hidden",
    marginBottom: "24px"
  }}>
        {}
        <div style={{
    padding: "16px 16px 0"
  }}>
          <h3 style={{
    margin: 0,
    fontSize: "16px",
    fontWeight: 600,
    lineHeight: "1.4",
    color: "var(--academy-text, #111827)"
  }}>
            {course.title}
          </h3>
          <div style={{
    display: "flex",
    gap: "12px",
    marginTop: "8px"
  }}>
            <span style={{
    display: "flex",
    alignItems: "center",
    gap: "5px",
    fontSize: "12px",
    color: "var(--academy-text-secondary, #6b7280)",
    padding: "3px 8px 3px 6px",
    borderRadius: "var(--ds-radius-sm)",
    border: "1px solid var(--academy-border, #e5e7eb)"
  }}>
              <BookIcon /> {lessons.length} lessons
            </span>
            <span style={{
    display: "flex",
    alignItems: "center",
    gap: "5px",
    fontSize: "12px",
    color: "var(--academy-text-secondary, #6b7280)",
    padding: "3px 8px 3px 6px",
    borderRadius: "var(--ds-radius-sm)",
    border: "1px solid var(--academy-border, #e5e7eb)"
  }}>
              <ClockIcon /> Approx. {totalDuration}
            </span>
          </div>
        </div>

        {}
        <div style={{
    padding: "14px 16px 16px"
  }}>
          <div style={{
    display: "flex",
    justifyContent: "space-between",
    fontSize: "12px",
    color: "var(--academy-text-secondary, #6b7280)"
  }}>
            <span>Your progress</span>
            <span style={{
    fontWeight: 500,
    color: "var(--academy-text, #111827)"
  }}>
              {percent}%
            </span>
          </div>
          <div style={{
    height: "6px",
    borderRadius: "var(--ds-radius-full)",
    background: "var(--academy-track, #f3f4f6)",
    marginTop: "8px",
    overflow: "hidden"
  }}>
            <div style={{
    height: "100%",
    borderRadius: "var(--ds-radius-full)",
    background: "var(--academy-progress, #3b82f6)",
    transition: "width 0.5s cubic-bezier(0.4, 0, 0.2, 1)",
    width: percent + "%"
  }} />
          </div>
        </div>

        {}
        <div className="academy-lessons-desktop">{lessonList}</div>

        {}
        <div className="academy-lessons-mobile">
          <button onClick={() => setExpanded(!expanded)} aria-expanded={expanded} style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    padding: "12px 16px",
    cursor: "pointer",
    borderTop: "1px solid var(--academy-border-subtle, #f3f4f6)",
    background: "transparent",
    border: "none",
    borderTopStyle: "solid",
    borderTopWidth: "1px",
    borderTopColor: "var(--academy-border-subtle, #f3f4f6)",
    width: "100%",
    textAlign: "left",
    color: "var(--academy-text-secondary, #6b7280)",
    fontSize: "13px",
    fontWeight: 500,
    fontFamily: "inherit"
  }}>
            <span>
              {expanded ? "Hide lessons" : "Show all " + lessons.length + " lessons"}
            </span>
            <ChevronDown open={expanded} />
          </button>
          {expanded && lessonList}
        </div>

        {}
        <div style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    borderTop: "1px solid var(--academy-border, #e5e7eb)",
    padding: "10px 16px"
  }}>
          {prev ? <a href={lessonPath(prev)} style={{
    fontSize: "13px",
    color: "var(--academy-text-secondary, #6b7280)",
    textDecoration: "none",
    display: "flex",
    alignItems: "center",
    gap: "4px"
  }}>
              ‹ Previous
            </a> : <div />}
          <button onClick={handleToggle} style={{
    fontSize: "13px",
    fontWeight: 500,
    cursor: "pointer",
    padding: "6px 14px",
    borderRadius: "var(--ds-radius-md)",
    border: isCurrentDone ? "1px solid var(--academy-border, #e5e7eb)" : "none",
    background: isCurrentDone ? "var(--academy-bg, #ffffff)" : "var(--academy-btn-bg, #111827)",
    color: isCurrentDone ? "var(--academy-complete, #10b981)" : "var(--academy-btn-text, #ffffff)",
    display: "flex",
    alignItems: "center",
    gap: "6px",
    transition: "all 0.2s",
    lineHeight: "1.4",
    fontFamily: "inherit"
  }}>
            {isCurrentDone ? <>
                <CheckCircle /> Completed
              </> : "Mark as completed"}
          </button>
          {next ? <a href={lessonPath(next)} style={{
    fontSize: "13px",
    color: "var(--academy-text-secondary, #6b7280)",
    textDecoration: "none",
    display: "flex",
    alignItems: "center",
    gap: "4px"
  }}>
              Next ›
            </a> : <div />}
        </div>
      </div>
    </div>;
};

<CourseTracker courseId="media-social-posting" lessonId="media-library" />

The media library is your centralized hub for all digital assets — images, videos, PDFs, documents, and GIFs. Every file you upload is available across all platform tools: your website builder, funnel pages, email templates, social planner, and more. Upload once and use it everywhere.

<Frame caption="The Media Library lesson in the HoopAI Academy Media and Social Posting section">
  <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-social-planner.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=4381831686ab5bc0082108f7f83c6dea" alt="Media library article" width="1536" height="826" data-path="images/academy-social-planner.png" />
</Frame>

## Why this matters

Without a centralized media library, the same logo, hero image, or product photo gets uploaded over and over across different tools. When your branding changes, you have to update it everywhere manually. The media library solves this completely — one location for all your assets, accessible instantly from any tool inside the platform.

## How to use the media library

<Steps>
  <Step title="Access the media library">
    Navigate to **Settings** > **Media** > **Open Media Library**, or access it directly from within any tool that allows image or file insertion — the funnel page builder, email editor, and social planner all have an embedded media picker.

    <Frame caption="Accessing the Media Library from within a platform tool">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-social-planner.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=4381831686ab5bc0082108f7f83c6dea" alt="Media library access from tools" width="1536" height="826" data-path="images/academy-social-planner.png" />
    </Frame>
  </Step>

  <Step title="Upload files">
    Click the **Upload** button. A file browser opens — select the files you want to upload from your computer. Supported file types include images (JPG, PNG, GIF, WebP), videos (MP4), documents (PDF, DOC), and more.

    Files appear in your media library immediately after upload and are ready to use in any tool.
  </Step>

  <Step title="Create folders for organization">
    Click **New Folder** and give it a descriptive name — for example, "Brand Assets," "Blog Images," or "Social Posts March 2026." Drag files into folders, or upload directly into the target folder.

    <Tip>
      Create a consistent folder structure from the start. Suggested folders: Brand Assets, Team Photos, Product Images, Social Content, Email Headers, and Logos. A clean library saves hours of searching over time.
    </Tip>
  </Step>

  <Step title="Use files in platform tools">
    When building a funnel page, designing an email, or creating a social post, click the media library icon to browse and insert files directly — no need to re-upload. The file is immediately available in its full quality.

    <Frame caption="Browsing and selecting files from the media library inside a platform editor">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-onboarding-connect-integrations.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=438d94999ada2e8819af2eb0ee159b50" alt="Using media library in platform tools" width="1536" height="826" data-path="images/academy-onboarding-connect-integrations.png" />
    </Frame>
  </Step>

  <Step title="Manage and delete files">
    Click the three-dot menu on any file to:

    * **Copy link:** Get a direct URL to the file for use outside the platform
    * **Copy to clipboard:** Copy the file for use elsewhere
    * **Delete:** Remove the file from the library

    Regularly review and remove unused files to keep your library clean and storage usage manageable.
  </Step>

  <Step title="Create images using Content AI">
    From the media library, click the **Content AI** button to generate a new AI image. Enter your description and style parameters. Generated images are saved directly to your library and ready to use immediately.

    <Frame caption="Generating an AI image from within the media library using Content AI">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-social-planner.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=4381831686ab5bc0082108f7f83c6dea" alt="AI image generation in media library" width="1536" height="826" data-path="images/academy-social-planner.png" />
    </Frame>
  </Step>
</Steps>

## Key points

<AccordionGroup>
  <Accordion title="Accessing media from within platform tools">
    You do not need to go to Settings to access your media library. When you click an image placeholder in the page builder, email editor, or social planner, a media picker opens directly. Your entire library is available from any media selection dialog.
  </Accordion>

  <Accordion title="Storage and file types">
    The media library supports a wide range of file types: PNG, JPG, GIF, WebP, SVG, MP4, PDF, DOC, DOCX, and more. Storage limits depend on your plan — check your account settings for current usage.
  </Accordion>

  <Accordion title="Sharing media with team members">
    The media library is shared across all users in your account. Team members can access, use, and upload files to the shared library, making collaboration on content creation seamless.
  </Accordion>
</AccordionGroup>

## Key benefits

<AccordionGroup>
  <Accordion title="Efficient workflow">
    Upload once, use everywhere — no repeated uploads across tools.
  </Accordion>

  <Accordion title="Better organization">
    Folders and a centralized library make it easy to find the exact asset you need.
  </Accordion>

  <Accordion title="Team collaboration">
    All team members share access to the same media library for consistent content.
  </Accordion>

  <Accordion title="Quick access">
    Accessible directly from within every tool that uses images or media.
  </Accordion>

  <Accordion title="AI image generation">
    Create custom images directly within the library using Content AI.
  </Accordion>
</AccordionGroup>
