> ## 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.

# Add a domain or subdomain

> Learn how to connect a custom domain or subdomain to the HoopAI Platform for your funnels, websites, and landing pages.

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="onboarding" lessonId="add-a-domain-or-subdomain" />

Connecting a custom domain to your funnels and websites is essential for a professional online presence. This lesson explains the difference between domains and subdomains, when to use each, and how to connect them through direct integration or manual DNS configuration.

<Frame caption="The Add a Domain or Subdomain lesson in the HoopAI Academy">
  <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-onboarding-dedicated-email-domain.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=86c5278f7c3ea103a8a1d4123ba136e5" alt="Add a domain or subdomain" width="1536" height="826" data-path="images/academy-onboarding-dedicated-email-domain.png" />
</Frame>

## Why this matters

A custom domain enhances your brand identity and credibility. Instead of sharing pages on a generic platform URL, your funnels and websites appear at your own branded address — reinforcing trust with every visitor.

***

## Understanding domains vs. subdomains

<AccordionGroup>
  <Accordion title="Domain vs. subdomain">
    A **domain** is your root web address (e.g., `yourbusiness.com`). A **subdomain** is a prefix added to your root domain (e.g., `store.yourbusiness.com` or `booking.yourbusiness.com`).

    If you already have a website on your root domain, use a subdomain to avoid conflicts. If you want to use the root domain exclusively for platform-built pages, you can connect it directly.
  </Accordion>

  <Accordion title="CNAME record vs. A record">
    * **CNAME record:** A DNS record that points a subdomain to another domain — used for subdomain connections
    * **A record:** A DNS record that points a domain directly to an IP address — used for root domain connections
  </Accordion>
</AccordionGroup>

***

## How to add a domain or subdomain

<Steps>
  <Step title="Navigate to Domains">
    Go to **Settings** in the left sidebar and select **Domains** (or go to **Sites** > **Domains** depending on your view).

    <Frame caption="The Domains settings page in the HoopAI Platform">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-onboarding-dedicated-email-domain.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=86c5278f7c3ea103a8a1d4123ba136e5" alt="Domains navigation" width="1536" height="826" data-path="images/academy-onboarding-dedicated-email-domain.png" />
    </Frame>
  </Step>

  <Step title="Click Add Domain">
    Click **Add Domain** and enter the domain or subdomain you want to connect — for example, `pages.yourbusiness.com`.
  </Step>

  <Step title="Choose your connection method">
    The platform offers two connection options:

    * **Direct Domain Connect Integration:** Available for domains registered with supported registrars (such as GoDaddy). The platform configures DNS settings automatically on your behalf.
    * **Manual Connection:** You add the DNS records yourself at your domain registrar.

    <Tip>
      If your registrar supports it, use Direct Domain Connect for the fastest and simplest setup — no DNS editing required.
    </Tip>
  </Step>

  <Step title="Add the DNS records manually (if needed)">
    If connecting manually, the platform will display the exact DNS records you need to add. Log in to your domain registrar's DNS management panel and add:

    * A **CNAME record** pointing your subdomain to the platform's provided hostname (for subdomains)
    * An **A record** pointing your root domain to the platform's IP address (for root domains)

    Save the records and allow 15 minutes to 48 hours for DNS propagation.

    <Frame caption="Adding DNS records at your domain registrar">
      <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="DNS records configuration" width="1536" height="826" data-path="images/academy-onboarding-connect-integrations.png" />
    </Frame>
  </Step>

  <Step title="Verify the connection">
    Return to the HoopAI Platform and click **Verify** or **Check DNS**. Once the records propagate, your domain status will show as verified and active.

    <Warning>
      DNS propagation can take up to 48 hours. If verification fails immediately, wait a few hours before trying again.
    </Warning>
  </Step>

  <Step title="Assign the domain to a funnel or website">
    After verification, go to your funnel or website settings and assign your connected domain. The platform will use this as the public-facing address for that funnel or website.

    <Frame caption="Assigning your connected domain to a funnel or website">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-onboarding-business-profile.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=16ee3d4747e0c5b5fdffec7483279cae" alt="Domain assignment to funnel" width="1536" height="826" data-path="images/academy-onboarding-business-profile.png" />
    </Frame>
  </Step>
</Steps>

***

## Key points

<AccordionGroup>
  <Accordion title="When to use a subdomain vs. the root domain">
    Use a subdomain if your root domain is already hosting an existing website. Use the root domain if you want all web presence managed within the HoopAI Platform and have no separate site.
  </Accordion>

  <Accordion title="How long DNS propagation takes">
    DNS changes can take anywhere from a few minutes to 48 hours to propagate globally. If your domain does not verify immediately, wait and try again before contacting support.
  </Accordion>

  <Accordion title="Using multiple domains">
    You can connect multiple domains or subdomains to your account. Each funnel or website can be assigned a different domain, allowing you to manage multiple brands or campaigns from one platform.
  </Accordion>
</AccordionGroup>

***

## Key benefits

<AccordionGroup>
  <Accordion title="Brand identity">
    A custom domain enhances your brand's credibility and professionalism with every visitor.
  </Accordion>

  <Accordion title="Full ownership">
    Connecting your own domain gives you complete control over your web address.
  </Accordion>

  <Accordion title="Flexibility with subdomains">
    Subdomains let you create dedicated sections for offers, booking, or products without affecting your main site.
  </Accordion>

  <Accordion title="Seamless integration">
    Connected domains work natively with all funnels and websites built inside the HoopAI Platform.
  </Accordion>

  <Accordion title="Multiple options">
    Both direct integration and manual DNS setup are supported, giving you flexibility regardless of your registrar.
  </Accordion>
</AccordionGroup>
