Skip to content

Commit dba3e2b

Browse files
committed
feat(shell-docs): align navbar CTAs with EIP, surface DLAI course banner
Brings the docs navbar, mobile nav, and top banner in line with the current product surfaces: - Navbar CTA relabeled "Free Developer Access" -> "Get Intelligence free" and reicon'd from Cloud to Lightbulb, matching the in-content OpsPlatformCTA default. The destination (Enterprise Intelligence Platform sign-up) is unchanged; the prior label and cloud icon misrepresented it as Copilot Cloud. - CTA breakpoint aligned with Docs/Reference: no longer hidden below 1100px. All three left-cluster links now share the same icon-hide behavior at <808px. - Top banner content swapped from "MCP Apps support" to the DeepLearning.AI "Build Interactive Agents with Generative UI" short course, which is already referenced from 6 generative-UI pages. External banner links now open in a new tab. - Mobile top nav gains the Talk-to-Engineer (gradient pill, calendar icon) and Get Intelligence free (lightbulb) CTAs from the desktop cluster, with the canonical mobile PostHog location string (docs_navbar_mobile) so analytics can split mobile from desktop. INTELLIGENCE_CTA_HREF and TALK_TO_ENGINEER_HREF are exported from brand-nav so MobileTopNav reuses the same URLs.
1 parent 9aa1db5 commit dba3e2b

4 files changed

Lines changed: 126 additions & 43 deletions

File tree

showcase/shell-docs/src/components/banners.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client";
22

33
import Link from "next/link";
4-
import { Rocket, X } from "lucide-react";
4+
import { GraduationCap, X } from "lucide-react";
55
import { useState, useEffect, useCallback } from "react";
66

77
// Time in milliseconds before a dismissed banner reappears
@@ -19,11 +19,12 @@ type BannerEntry = {
1919

2020
const bannerContent: BannerEntry[] = [
2121
{
22-
icon: <Rocket className="w-5 h-5 hidden md:block flex-shrink-0" />,
23-
mobileText: "CopilotKit fully supports MCP Apps!",
24-
desktopText: "Bring MCP Apps interaction to your users with CopilotKit!",
25-
buttonText: "See What's New",
26-
href: "/generative-ui/mcp-apps",
22+
icon: <GraduationCap className="w-5 h-5 hidden md:block flex-shrink-0" />,
23+
mobileText: "Free Generative UI course on DeepLearning.AI",
24+
desktopText:
25+
"Build Interactive Agents with Generative UI: our new free DeepLearning.AI course",
26+
buttonText: "Start the course",
27+
href: "https://www.deeplearning.ai/short-courses/build-interactive-agents-with-generative-ui/",
2728
},
2829
];
2930

@@ -146,6 +147,12 @@ export function Banners() {
146147
</div>
147148
<Link
148149
href={content.href}
150+
target={content.href.startsWith("http") ? "_blank" : undefined}
151+
rel={
152+
content.href.startsWith("http")
153+
? "noopener noreferrer"
154+
: undefined
155+
}
149156
className="text-xs md:text-sm items-center flex px-2 py-0.5 md:px-4 md:py-1 no-underline whitespace-nowrap rounded-lg flex-shrink-0 transition-all duration-100"
150157
style={{
151158
background: "var(--accent-light, rgba(109, 69, 249, 0.12))",

showcase/shell-docs/src/components/brand-nav.tsx

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,28 @@ import { SearchTrigger } from "./search-trigger";
77
import { CopilotKitMark } from "./copilotkit-mark";
88
import RocketIcon from "./icons/rocket";
99
import ConsoleIcon from "./icons/console";
10-
import CloudIcon from "./icons/cloud";
10+
import LightbulbIcon from "./icons/lightbulb";
1111
import ExternalLinkIcon from "./icons/external-link";
1212

13-
// Cloud sign-up CTA destination. UTM params let marketing attribute
14-
// navbar-driven sign-ups distinctly from in-content SignupLink clicks.
15-
const CLOUD_CTA_HREF =
13+
// Enterprise Intelligence Platform sign-up CTA. UTM params let marketing
14+
// attribute navbar-driven sign-ups distinctly from in-content SignupLink
15+
// and OpsPlatformCTA clicks. Exported so MobileTopNav reuses the same URL.
16+
export const INTELLIGENCE_CTA_HREF =
1617
"https://dashboard.operations.copilotkit.ai/?utm_source=docs&utm_medium=cta&utm_campaign=intelligence&utm_content=navbar";
1718

18-
// LEFT cluster — Docs / Reference / Free Developer Access. Visual pattern
19-
// (icon-next-to-label) mirrors canonical.
19+
export const TALK_TO_ENGINEER_HREF =
20+
"https://copilotkit.ai/talk-to-an-engineer";
21+
22+
// LEFT cluster — Docs / Reference / Intelligence sign-up. Visual pattern
23+
// (icon-next-to-label) mirrors canonical. The third slot label matches the
24+
// in-content OpsPlatformCTA default ("Get Intelligence free") so the
25+
// conversion path reads consistently from navbar to body to footer.
2026
type LeftLink = {
2127
href: string;
2228
label: string;
2329
icon: React.ReactNode;
2430
target?: "_blank" | "_self";
2531
showExternalLinkIcon?: boolean;
26-
// Free Developer Access only renders at ≥1100px (same breakpoint as the
27-
// Talk-to-Engineer pill). Below that, the navbar is too crowded; the
28-
// in-content `<SignupLink>` components on quickstart and feature pages
29-
// carry the conversion path.
30-
hideAtNarrow?: boolean;
3132
};
3233

3334
const LEFT_LINKS: LeftLink[] = [
@@ -42,12 +43,11 @@ const LEFT_LINKS: LeftLink[] = [
4243
href: "/reference",
4344
},
4445
{
45-
icon: <CloudIcon className="text-[var(--text-secondary)]" />,
46-
label: "Free Developer Access",
47-
href: CLOUD_CTA_HREF,
46+
icon: <LightbulbIcon className="text-[var(--text-secondary)]" />,
47+
label: "Get Intelligence free",
48+
href: INTELLIGENCE_CTA_HREF,
4849
target: "_blank",
4950
showExternalLinkIcon: true,
50-
hideAtNarrow: true,
5151
},
5252
];
5353

@@ -69,7 +69,7 @@ export function BrandNav(_props: BrandNavProps = {}) {
6969

7070
const handleTalkToEngineersClick = () => {
7171
posthog?.capture("talk_to_us_clicked", { location: "docs_nav" });
72-
window.location.href = "https://copilotkit.ai/talk-to-an-engineer";
72+
window.location.href = TALK_TO_ENGINEER_HREF;
7373
};
7474

7575
const handleFreeDeveloperAccessClick = () => {
@@ -103,17 +103,10 @@ export function BrandNav(_props: BrandNavProps = {}) {
103103
</Link>
104104
<ul className="hidden gap-6 items-center h-full md:flex me-auto">
105105
{LEFT_LINKS.map((link) => {
106-
const hideIconAtNarrow =
107-
link.label === "Docs" || link.label === "Reference";
108106
const isActive = activeRoute === link.href;
109-
const isFreeDevAccess = link.label === "Free Developer Access";
107+
const isFreeDevAccess = link.label === "Get Intelligence free";
110108
return (
111-
<li
112-
key={link.href}
113-
className={`relative h-full group ${
114-
link.hideAtNarrow ? "[@media(width<1100px)]:hidden" : ""
115-
}`}
116-
>
109+
<li key={link.href} className="relative h-full group">
117110
<Link
118111
href={link.href}
119112
target={link.target}
@@ -127,13 +120,7 @@ export function BrandNav(_props: BrandNavProps = {}) {
127120
} hover:opacity-100 transition-opacity duration-300`}
128121
>
129122
<span className="flex gap-2 items-center h-full text-[var(--text-secondary)]">
130-
<span
131-
className={
132-
hideIconAtNarrow
133-
? "[@media(width<808px)]:hidden"
134-
: ""
135-
}
136-
>
123+
<span className="[@media(width<808px)]:hidden">
137124
{link.icon}
138125
</span>
139126
<span className="text-sm font-medium whitespace-nowrap">
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from "react";
2+
3+
interface LightbulbIconProps {
4+
className?: string;
5+
}
6+
7+
const DEFAULT_CLASSNAME = "text-icon";
8+
9+
const LightbulbIcon = ({ className }: LightbulbIconProps) => {
10+
return (
11+
<svg
12+
width="20"
13+
height="20"
14+
viewBox="0 0 20 20"
15+
fill="none"
16+
xmlns="http://www.w3.org/2000/svg"
17+
className={[DEFAULT_CLASSNAME, className].filter(Boolean).join(" ")}
18+
>
19+
<path
20+
d="M11.875 17.5C11.875 17.6658 11.8092 17.8247 11.6919 17.9419C11.5747 18.0592 11.4158 18.125 11.25 18.125H8.75C8.58424 18.125 8.42527 18.0592 8.30806 17.9419C8.19085 17.8247 8.125 17.6658 8.125 17.5C8.125 17.3342 8.19085 17.1753 8.30806 17.0581C8.42527 16.9408 8.58424 16.875 8.75 16.875H11.25C11.4158 16.875 11.5747 16.9408 11.6919 17.0581C11.8092 17.1753 11.875 17.3342 11.875 17.5ZM16.875 8.125C16.8767 9.16091 16.6432 10.1837 16.1922 11.1167C15.7411 12.0497 15.0844 12.8688 14.2719 13.5125C14.0857 13.6594 13.9354 13.8474 13.832 14.0617C13.7285 14.2761 13.6747 14.5113 13.6747 14.7492V15.625C13.6747 15.9565 13.543 16.2745 13.3086 16.5089C13.0742 16.7433 12.7562 16.875 12.4247 16.875H7.5C7.16848 16.875 6.85054 16.7433 6.61612 16.5089C6.3817 16.2745 6.25 15.9565 6.25 15.625V14.7492C6.25 14.5133 6.19686 14.2803 6.09452 14.0671C5.99218 13.8538 5.84324 13.6661 5.65859 13.5172C4.85194 12.8778 4.19914 12.0658 3.74865 11.1407C3.29816 10.2155 3.06158 9.20057 3.05625 8.17109C3.03281 4.4625 6.025 1.39219 9.72734 1.25469C10.6437 1.22043 11.5573 1.37206 12.4135 1.70043C13.2697 2.02881 14.0508 2.5273 14.7104 3.16559C15.3699 3.80388 15.8945 4.56861 16.2528 5.41386C16.6111 6.25911 16.7959 7.16778 16.7969 8.08594L16.875 8.125ZM15.625 8.125C15.624 7.33968 15.4661 6.56254 15.1604 5.83946C14.8547 5.11637 14.4072 4.46202 13.8442 3.91549C13.2812 3.36895 12.6141 2.94114 11.8826 2.65692C11.1511 2.3727 10.3699 2.23774 9.58516 2.26016C6.4625 2.37734 3.93828 4.96094 3.95781 8.16172C3.96221 9.00329 4.16544 9.83185 4.5494 10.5803C4.93336 11.3287 5.48732 11.9756 6.16797 12.4703C6.50923 12.7196 6.7869 13.0464 6.97818 13.4239C7.16947 13.8014 7.26896 14.219 7.26875 14.6422V15.625H12.4188V14.7492C12.418 14.3245 12.5163 13.9053 12.7057 13.5247C12.8952 13.144 13.1707 12.8128 13.5102 12.557C14.1722 12.0331 14.7071 11.3664 15.0742 10.6063C15.4413 9.84616 15.6313 9.01183 15.6297 8.16719L15.625 8.125ZM10 4.375C9.00544 4.375 8.05161 4.77009 7.34835 5.47335C6.64509 6.17661 6.25 7.13044 6.25 8.125C6.25 8.29076 6.31585 8.44973 6.43306 8.56694C6.55027 8.68415 6.70924 8.75 6.875 8.75C7.04076 8.75 7.19973 8.68415 7.31694 8.56694C7.43415 8.44973 7.5 8.29076 7.5 8.125C7.5 7.46196 7.76339 6.82607 8.23223 6.35723C8.70107 5.88839 9.33696 5.625 10 5.625C10.1658 5.625 10.3247 5.55915 10.4419 5.44194C10.5592 5.32473 10.625 5.16576 10.625 5C10.625 4.83424 10.5592 4.67527 10.4419 4.55806C10.3247 4.44085 10.1658 4.375 10 4.375Z"
21+
fill="currentColor"
22+
/>
23+
</svg>
24+
);
25+
};
26+
27+
export default LightbulbIcon;

showcase/shell-docs/src/components/mobile-top-nav.tsx

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,45 @@
33
import Link from "next/link";
44
import { SidebarTrigger } from "fumadocs-ui/components/layout/sidebar";
55
import { Menu } from "lucide-react";
6+
import { usePostHog } from "posthog-js/react";
67
import { SearchTrigger } from "./search-trigger";
78
import { CopilotKitMark } from "./copilotkit-mark";
9+
import LightbulbIcon from "./icons/lightbulb";
10+
import { INTELLIGENCE_CTA_HREF, TALK_TO_ENGINEER_HREF } from "./brand-nav";
811

912
// Mobile-only top nav. Replaces shell-docs's BrandNav on small viewports
10-
// because BrandNav's full chrome (4 tabs + right cluster + slanted SVG
11-
// wings) doesn't fit. Rendered via DocsLayout's `nav.component` slot so
12-
// it sits INSIDE the SidebarProvider — `SidebarTrigger` toggles the
13-
// Fumadocs mobile sidebar (`#nd-sidebar-mobile`), which natively renders
14-
// the page tree we pass to DocsLayout.
13+
// because BrandNav's full chrome (3 tabs + Talk-to-Engineer pill +
14+
// slanted SVG wings) doesn't fit. Rendered via DocsLayout's
15+
// `nav.component` slot so it sits INSIDE the SidebarProvider —
16+
// `SidebarTrigger` toggles the Fumadocs mobile sidebar
17+
// (`#nd-sidebar-mobile`), which natively renders the page tree we pass
18+
// to DocsLayout.
1519
//
1620
// Positioned `fixed` (mirrors Fumadocs's default Navbar) because the
1721
// nav.component slot otherwise becomes a flex-row sibling of LayoutBody
1822
// inside shell-docs's outer `<main className="flex …">` — without
1923
// fixed positioning, the nav swallows the left half of the viewport.
24+
//
25+
// The Talk-to-Engineer and Get-Intelligence-free CTAs mirror the
26+
// desktop BrandNav cluster: same destinations, same PostHog events
27+
// (`talk_to_us_clicked` / `try_for_free_clicked`) with `location:
28+
// "docs_navbar_mobile"` so analytics can split mobile from desktop
29+
// (which uses `docs_nav` / `docs_navbar_left`). Matches the canonical
30+
// docs MobileSidebar pattern.
2031
export function MobileTopNav() {
32+
const posthog = usePostHog();
33+
34+
const handleTalkToEngineersClick = () => {
35+
posthog?.capture("talk_to_us_clicked", { location: "docs_navbar_mobile" });
36+
window.location.href = TALK_TO_ENGINEER_HREF;
37+
};
38+
39+
const handleIntelligenceClick = () => {
40+
posthog?.capture("try_for_free_clicked", {
41+
location: "docs_navbar_mobile",
42+
});
43+
};
44+
2145
return (
2246
<header
2347
id="nd-subnav"
@@ -39,6 +63,44 @@ export function MobileTopNav() {
3963
Docs
4064
</span>
4165
</Link>
66+
{/* Get Intelligence free — muted icon, matches the desktop
67+
* BrandNav treatment for the same CTA. */}
68+
<Link
69+
href={INTELLIGENCE_CTA_HREF}
70+
target="_blank"
71+
rel="noopener noreferrer"
72+
onClick={handleIntelligenceClick}
73+
aria-label="Get Intelligence free"
74+
title="Get Intelligence free"
75+
className="flex items-center justify-center w-10 h-10 rounded-md text-[var(--text-muted)] hover:text-[var(--text)] hover:bg-[var(--bg-elevated)]"
76+
>
77+
<LightbulbIcon />
78+
</Link>
79+
{/* Talk to an Engineer — compact gradient pill, mirrors the
80+
* desktop md-to-1099px calendar button. */}
81+
<button
82+
type="button"
83+
onClick={handleTalkToEngineersClick}
84+
aria-label="Talk to an engineer"
85+
title="Talk to an Engineer"
86+
className="flex justify-center items-center w-9 h-9 rounded-full bg-gradient-to-r from-indigo-500/90 to-purple-500/90 text-white shadow-sm hover:from-indigo-500 hover:to-purple-500 hover:shadow-md transition-all duration-200 cursor-pointer relative overflow-hidden after:content-[''] after:absolute after:inset-0 after:bg-gradient-to-r after:from-transparent after:via-white/30 after:to-transparent after:-translate-x-full hover:after:translate-x-[100%] after:transition-transform after:duration-700 after:pointer-events-none"
87+
>
88+
<svg
89+
width="18"
90+
height="18"
91+
viewBox="0 0 24 24"
92+
fill="none"
93+
stroke="currentColor"
94+
strokeWidth={2}
95+
strokeLinecap="round"
96+
strokeLinejoin="round"
97+
>
98+
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
99+
<line x1="16" y1="2" x2="16" y2="6" />
100+
<line x1="8" y1="2" x2="8" y2="6" />
101+
<line x1="3" y1="10" x2="21" y2="10" />
102+
</svg>
103+
</button>
42104
<SearchTrigger />
43105
<SidebarTrigger
44106
className="flex items-center justify-center w-10 h-10 -mr-1 rounded-md text-[var(--text-muted)] hover:text-[var(--text)] hover:bg-[var(--bg-elevated)]"

0 commit comments

Comments
 (0)