From 79b5a5a18d645b77825ef5039df581469885541b Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Tue, 25 Nov 2025 17:00:57 +0100 Subject: [PATCH 01/58] Rename learn/index to learn/introduction --- src/pages/learn/{index.mdx => introduction.mdx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/pages/learn/{index.mdx => introduction.mdx} (100%) diff --git a/src/pages/learn/index.mdx b/src/pages/learn/introduction.mdx similarity index 100% rename from src/pages/learn/index.mdx rename to src/pages/learn/introduction.mdx From f0ce47aabcec1d1ec83a983d6cde1fb5324cd559 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Tue, 25 Nov 2025 17:01:13 +0100 Subject: [PATCH 02/58] Switch the /docs redirect to go to /introduction --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index ebc5d887e0..244e7c6f2c 100644 --- a/vercel.json +++ b/vercel.json @@ -602,7 +602,7 @@ }, { "source": "/docs", - "destination": "/learn", + "destination": "/learn/introduction/", "permanent": true }, { From 71a276aa11020b879638e184fcfa9871cabb4bc0 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Tue, 25 Nov 2025 17:03:05 +0100 Subject: [PATCH 03/58] Add new (now empty) Learn index page --- src/components/sidebar/index.tsx | 6 +++++- src/pages/learn/_meta.ts | 11 ++++++++++- src/pages/learn/index.mdx | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/pages/learn/index.mdx diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 2d4733bf0c..2db9ecc0b4 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -249,7 +249,7 @@ function File({ item: PageItem | Item anchors: Heading[] onFocus: FocusEventHandler -}): ReactElement { +}) { const route = useFSRoute() // It is possible that the item doesn't have any route - for example an external link. @@ -261,6 +261,10 @@ function File({ const activeAnchor = useActiveAnchor() as ActiveAnchor | null const { setMenu } = useMenu() + if (item.type === "hidden") { + return null + } + if (item.type === "separator") { return } diff --git a/src/pages/learn/_meta.ts b/src/pages/learn/_meta.ts index 00f65b80e6..32df28adc8 100644 --- a/src/pages/learn/_meta.ts +++ b/src/pages/learn/_meta.ts @@ -3,7 +3,16 @@ export default { type: "separator", title: "Learn", }, - index: "Introduction", + index: { + /** + * The Learn aggregator is hidden from the Sidebar. + */ + type: "hidden", + theme: { + layout: "raw", + }, + }, + introduction: "Introduction", schema: "Schemas and Types", queries: "", mutations: "", diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx new file mode 100644 index 0000000000..8754b08baa --- /dev/null +++ b/src/pages/learn/index.mdx @@ -0,0 +1 @@ +Learn From fc769de886439a1a83a0f617ac0029f0c9bd21f4 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Tue, 25 Nov 2025 17:23:08 +0100 Subject: [PATCH 04/58] Add TocHero and TocHeroContents --- src/components/toc-hero/index.tsx | 35 +++++++++++++++++++++++++++++++ src/pages/learn/index.mdx | 17 ++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/components/toc-hero/index.tsx diff --git a/src/components/toc-hero/index.tsx b/src/components/toc-hero/index.tsx new file mode 100644 index 0000000000..e0f3ba9994 --- /dev/null +++ b/src/components/toc-hero/index.tsx @@ -0,0 +1,35 @@ +import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr" + +export interface TocHeroProps { + heading: string +} +export function TocHero({ heading }: TocHeroProps) { + return ( +
+

{heading}

+
+ ) +} + +export function TocHeroContents({ ids }: { ids: string[] }) { + return ( +
+

+ What will you find here? +

+ +
+ ) +} diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 8754b08baa..0b012f0280 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -1 +1,16 @@ -Learn +import { Button } from '@/app/conf/_design-system/button'; +import { TocHero, TocHeroContents } from '../../components/toc-hero'; + + + + + + + From 572834c9919b4008abdfa9716830bdc01f5ef025 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:11:33 +0100 Subject: [PATCH 05/58] Add Eyebrow component --- src/_design-system/eyebrow.tsx | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/_design-system/eyebrow.tsx diff --git a/src/_design-system/eyebrow.tsx b/src/_design-system/eyebrow.tsx new file mode 100644 index 0000000000..f346dadf0d --- /dev/null +++ b/src/_design-system/eyebrow.tsx @@ -0,0 +1,30 @@ +import { clsx } from "clsx" + +import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr" + +export interface EyebrowProps extends React.HTMLAttributes { + children: React.ReactNode + className?: string + as?: "p" | "span" | "h2" | "h3" | "h4" | "h5" | "h6" +} + +export function Eyebrow({ + children, + className, + as = "span", + ...rest +}: EyebrowProps) { + const Root = as + return ( + + + {children} + + ) +} From 5a79d05afd6667cf73aab25eadbb5afa6a5e45e7 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:58:10 +0100 Subject: [PATCH 06/58] Use proper icon --- src/_design-system/eyebrow.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_design-system/eyebrow.tsx b/src/_design-system/eyebrow.tsx index f346dadf0d..b75694c05d 100644 --- a/src/_design-system/eyebrow.tsx +++ b/src/_design-system/eyebrow.tsx @@ -1,6 +1,6 @@ import { clsx } from "clsx" -import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr" +import { ChevronRight } from "@/app/conf/_design-system/pixelarticons/chevron-right" export interface EyebrowProps extends React.HTMLAttributes { children: React.ReactNode @@ -23,7 +23,7 @@ export function Eyebrow({ )} {...rest} > - + {children} ) From 7786c8d8052b697f2ca0a665a9826ba6d113cd5c Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:58:33 +0100 Subject: [PATCH 07/58] Extract NavbarFixed --- src/app/not-found.tsx | 3 ++- src/components/index-page/index.tsx | 3 ++- src/components/navbar/navbar-fixed.tsx | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 src/components/navbar/navbar-fixed.tsx diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index e848d35314..b2da8e0b93 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -8,6 +8,7 @@ import stripesMask from "@/components/404-page/image.webp" import { Button } from "./conf/_design-system/button" import MainLayout from "./(main)/layout" +import { NavbarFixed } from "@/components/navbar/navbar-fixed" export default function NotFoundPage() { const pathname = usePathname() @@ -29,7 +30,7 @@ export default function NotFoundPage() { return ( - +
diff --git a/src/components/index-page/index.tsx b/src/components/index-page/index.tsx index 1de9f96c7b..dbdb379a78 100644 --- a/src/components/index-page/index.tsx +++ b/src/components/index-page/index.tsx @@ -12,6 +12,7 @@ import { JoinTheCommunity } from "./join-the-community" import { DataColocation } from "./data-colocation" import { WhatIsGraphQL } from "./what-is-graphql" import { UseCases } from "./use-cases" +import { NavbarFixed } from "../navbar/navbar-fixed" export function IndexPage() { return ( @@ -35,7 +36,7 @@ export function IndexPage() { - +
) } diff --git a/src/components/navbar/navbar-fixed.tsx b/src/components/navbar/navbar-fixed.tsx new file mode 100644 index 0000000000..b7407bc4ac --- /dev/null +++ b/src/components/navbar/navbar-fixed.tsx @@ -0,0 +1,3 @@ +export function NavbarFixed() { + return +} From bb510999499f4e2f2b15b8213bbf75c6ddfb911f Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:58:47 +0100 Subject: [PATCH 08/58] Grab blur beans from Figma --- .../community/events/events-blur-bean.webp | Bin 0 -> 58330 bytes .../learn-aggregator/learn-blur-bean.webp | Bin 0 -> 74746 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/app/(main)/community/events/events-blur-bean.webp create mode 100644 src/components/learn-aggregator/learn-blur-bean.webp diff --git a/src/app/(main)/community/events/events-blur-bean.webp b/src/app/(main)/community/events/events-blur-bean.webp new file mode 100644 index 0000000000000000000000000000000000000000..679526360c1d9955d1b286ee365d4ab4fd129ee3 GIT binary patch literal 58330 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 literal 0 HcmV?d00001 diff --git a/src/components/learn-aggregator/learn-blur-bean.webp b/src/components/learn-aggregator/learn-blur-bean.webp new file mode 100644 index 0000000000000000000000000000000000000000..65b680af5b65ed360eec383a1170f732d290c71d GIT binary patch literal 74746 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%0Aq9`G@7>jB_PZFTH|` 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

!ouR4o0{`D0X4>VV^{v~Fb_w;oQo z6<8-o&8z|c1 z_~WdO^ZTmz`P)U;ex9xu=ff{TF?+GETKi!{5q+wp27Lz=TL;HlQ4C+L7v#vARSsrV zX?6(TYN!K5KM^G?>4j|#w>3!%qwip?TT2F4(u<7R4%T0NobN&9o>;b3%7Ki}a^2}`+BI~QKxuSWJ72!E~2Q2eGjm& z9MsWgmfGA^p&r;_YHia9jIOrhw-q5V^{2IM!naq5aa}2`S+&NlRjK@n zi^|#i9zm^V^=92ItmO36+zt5ae%AdwmfiQd?`#iBKptFEqFul~M| z>ic>A{v6fI_TtvA5B5{dz<}blIqw%~NXC(>1GajgA?!ONQger`piq&XTWPvD0=1cI zi$7*TG6MH_wziEU4Jxp%00#lCAmCw;A+6d!;Qhh3ttCB3HcFs?GUefOnHBpV-#o90 zHOv{LY#mp75L3LrukNT1)@4UC^Q^Uty`;C(zS=j|0E8Z@eZ5#E(}B!8z$lTIyh0)%b-X+hY!b!B_{0)?7Itt(PHZ*_9~ij9xwVY#WScLdBg zX2$I6@9yt%J(wKb5g!h0R{+tFQ)h@p*Fjf*XEEo?QC0nCaeVm`X|?LpxtKEHp%7(g z>;bR_>nrur12|1bS!!*Y#W>P9w9*La{BcmItn+T`N=v-t#cdChzLIUN%pf@*Brl$C z-%pXOROBHnV(D68yUN0@ToWez`(01uoZL9FI6%8`iETGrL0gA-T{DeBuWy#;;vWyM z6AXU9%TOKatJNwxn|f69A{ss$J9yq67}Hg(KY|qo#FZ$wW-D=;c`P>$u^Ow*RYw7B zrw+FkXnR4$X zW!zP--Z5%GUv+t1&P}fgP_egpWwK-8Nk@YZO7lu>%&DxCXNVERpZHapxr4WoKk(@5 ziqTnGSBOq1(E@Apxvs?Pchy!}A*0g5->bQew)r1+b zJGy%y*8@P<>P2Y1ggbtr&LpxWjYBD7OY6%cSM^Vf?YRz#}|Hq`5UE48o%Es27Vc3oj7=1dSTj+96E zVK`ztXVs2aOUZoG=yg4KfB#wi9M^YTj^V8TPk-r zYR8c{{)mK=6@f4-By0`15(a2xP3X!b6-wSV6lIu^vvh{qUs?3bzmbC@H>8xz1*Wje znwX9qrOWPzTwF&u1Gh2Ck#KDEd)?UX8234bRsY$ie)Pf5W4CW~b~~KCsPxMB*x~Kr zR24)kqfAokun&w{>R3Tqi4H{4Ox)In$y|S=Jy;pIt!r}H)^(+28c4%Xh1#HYgi-5y zI9b)>{Y6+>EEEe{In1sL(K1GU4NANtKcaf304uDAfvmb^A|#F1^*Xe=s=sg2KYQO- z9kH4<8L=*M_}1>B#+r!(sbUA5>yV9Ip-TNR4Y3F=0bN_yT$IY;2)Rh!N}&{!Rycg> z{6l%bDiy0e{Qp69ZesP8r;INQVKEIE4#jnRcAd2wh%IYYwyYkOLc(Uuam~Dgt>b>t z`p zb?d&R@q`FpO*<4c{NOcj{Mt|L|KR7Qb!GUHt8svo(;R7yupUa&k=ym?9ZEK|nu_{vStdfyN`SKAT_rV(LDG{xu`zD*R zUGuZJ>vdg6m2`b|RFqM)uL_EUj1m$8l1d|;LrQlH-OW(aT>=i>jUdf1!_Y$th;$0b z(9%70H;;GkTlcQF-hKam>s#lXz0Wzj&fdTM+-F&GniPMH3@@dcKuWI_`zOXhdA#R? zi(dUf)GDy>%lDD{s&eh4gngPR19(JCjD|FQ8nEuufWk?;+2;>MuA&w+Vq+iZV201M z>cQ(m*tW zDNe6G*+<9Th2>nuY5XG_SvQk8`9mc%E&}z2=YUK&(@&8D!5BKb)6-97>3C!JUh=g* zp$!iSpB!I3>eVIy=x;ObG}mkN=}Aya=hWfTyMQO}@+R-EX9NBK#go#KtHMiI9F%qk z!lZIPw6)wezu@Rf*%N*EDTr5-x%FvzyjhR(LG_q@0q}d! z$caHy6HFfL=o{75~24TBMIUuB93pCT)zchXTifrzsZ; zJb$sK0sY2jtu~`m*=OkW0?&_{f~4wu)KGxW7#-T9vm(O zeZ7cLanVb>eThZ=*^9aYK^FD;5u<`UJ%PpLF+h-V+u$O4OMdZv^CG`~LBw9ub)L2x zR1)r?XW^w6Xr$wr9zM)lnrJC}F0aoxDmU@rC){g-9~lpmLcjmH&`yGCo1H^E2GWeX zjn&4km8L0n1wdb3+aVxHJ{Ww36B2Qyh?m8a^|W@cgAC_pCBD`_D|D1%`OTOx+a_ST z*tvZpKhtn(7J4#U}QE4gIvUpU?@1|qWCCm-AKVV9-kKi&W_i_&DEU5QZq z=`HXiL1RvbX{yGY!X$6tV%8#K05s?H*V=<%l0Atg4zQ`uES3ZAK<+hl+3|tUjyLVn z>Z}pZmI;3-wR`8hx%K1KW@WRIJQs)OB%xN>>cs4GVU;0?!f#Qr4u2BV7{ta0XrzTD zVk!!bM&P)GD$l zSN+Me=dHaCgGLwScXT;(b8uHu&l=9wt*x%MzmwMP+Qe^)E2l+}Sdqy(yXgn?Rns-U#E@=_|sVc&JH`Kl)P0FlL7bLS)U|Mp*Njc&ygi z%0D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 Date: Wed, 26 Nov 2025 19:59:05 +0100 Subject: [PATCH 09/58] Perfect TOC Hero Contents --- src/components/toc-hero/toc-hero-contents.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/components/toc-hero/toc-hero-contents.tsx diff --git a/src/components/toc-hero/toc-hero-contents.tsx b/src/components/toc-hero/toc-hero-contents.tsx new file mode 100644 index 0000000000..f8d75d1d7c --- /dev/null +++ b/src/components/toc-hero/toc-hero-contents.tsx @@ -0,0 +1,36 @@ +import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr" +import { ChevronRight } from "@/app/conf/_design-system/pixelarticons/chevron-right" + +export interface TocHeroContentsProps + extends React.HTMLAttributes { + sections: string[] +} + +export function TocHeroContents({ + sections: sections, + ...rest +}: TocHeroContentsProps) { + return ( +

+

+ What will you find here? +

+ +
+ ) +} From 24d4f66a9a919aa6a96229002246ff0173fb2adc Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:59:22 +0100 Subject: [PATCH 10/58] Finalize TocHero styles --- src/components/toc-hero/index.tsx | 39 ++++++++++--------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/components/toc-hero/index.tsx b/src/components/toc-hero/index.tsx index e0f3ba9994..872069ac03 100644 --- a/src/components/toc-hero/index.tsx +++ b/src/components/toc-hero/index.tsx @@ -1,35 +1,20 @@ -import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr" +export { TocHeroContents } from "./toc-hero-contents" export interface TocHeroProps { heading: string + text: React.ReactNode + children: React.ReactNode + decoration: React.ReactNode } -export function TocHero({ heading }: TocHeroProps) { +export function TocHero({ heading, text, children, decoration }: TocHeroProps) { return ( -
-

{heading}

+
+ {decoration} +
+

{heading}

+

{text}

+ {children} +
) } - -export function TocHeroContents({ ids }: { ids: string[] }) { - return ( -
-

- What will you find here? -

- -
- ) -} From 79b43a352df60e5c108a5185e883635d6e53be25 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:59:45 +0100 Subject: [PATCH 11/58] Add LearnHeroStripes component --- src/components/learn-aggregator/index.tsx | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/components/learn-aggregator/index.tsx diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx new file mode 100644 index 0000000000..4d6be25c71 --- /dev/null +++ b/src/components/learn-aggregator/index.tsx @@ -0,0 +1,33 @@ +import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" + +import blurBean from "./learn-blur-bean.webp" + +// https://www.figma.com/design/aPUvZDSxJfYDJtPd7GF2sB/GraphQL.org--Working-File?node-id=5768-48498&m=dev +export function TeaserSection() { + return
+} + +export function LearnHeroStripes() { + return ( +
+ +
+ ) +} From ec2dd4596452c236e0f34aa99ca5a310df44601c Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 19:59:57 +0100 Subject: [PATCH 12/58] Commit Learn Hero --- src/pages/learn/index.mdx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 0b012f0280..293d287c4b 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -1,16 +1,26 @@ import { Button } from '@/app/conf/_design-system/button'; + import { TocHero, TocHeroContents } from '../../components/toc-hero'; +import { TeaserSection, LearnHeroStripes } from '../../components/learn-aggregator' +import { NavbarFixed } from '../../components/navbar/navbar-fixed' + + Get hands-on with the fundamentals of GraphQL. Start with the basics and see how it compares to other technologies. +
{" "} + Then move on to best practices for designing better APIs. + + } + decoration={} > - -
From 1fdd5fa6e9a4d5afd452c79faf3afd3bd9ca211e Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 20:39:32 +0100 Subject: [PATCH 13/58] Tweak styles, add ids --- .../community/events/benefits-section.tsx | 4 +- .../get-your-meetup-noticed-section.tsx | 6 +- src/app/(main)/community/events/page.tsx | 188 +++++++++++------- src/components/toc-hero/index.tsx | 4 +- src/components/toc-hero/toc-hero-contents.tsx | 52 +++-- src/pages/learn/index.mdx | 1 + 6 files changed, 165 insertions(+), 90 deletions(-) diff --git a/src/app/(main)/community/events/benefits-section.tsx b/src/app/(main)/community/events/benefits-section.tsx index bb0d333bd9..1a2f9997de 100644 --- a/src/app/(main)/community/events/benefits-section.tsx +++ b/src/app/(main)/community/events/benefits-section.tsx @@ -5,9 +5,9 @@ import EyeIcon from "@/app/conf/_design-system/pixelarticons/eye.svg?svgr" import { BenefitCard } from "./benefit-card" -export function BenefitsSection() { +export function BenefitsSection({ id }: { id?: string }) { return ( -
+

Benefits of getting involved diff --git a/src/app/(main)/community/events/get-your-meetup-noticed-section.tsx b/src/app/(main)/community/events/get-your-meetup-noticed-section.tsx index be2b784624..b897330feb 100644 --- a/src/app/(main)/community/events/get-your-meetup-noticed-section.tsx +++ b/src/app/(main)/community/events/get-your-meetup-noticed-section.tsx @@ -2,9 +2,9 @@ import Mailbox from "./mailbox.svg?svgr" import { Button } from "@/app/conf/_design-system/button" import { DISCORD_CHANNEL_LINK, DISCORD_SERVER_LINK } from "./links" -export function GetYourMeetupNoticedSection() { +export function GetYourMeetupNoticedSection({ id }: { id?: string }) { return ( -
+

@@ -41,7 +41,7 @@ export function GetYourMeetupNoticedSection() { Go to Discord

-
+
diff --git a/src/app/(main)/community/events/page.tsx b/src/app/(main)/community/events/page.tsx index 376f5b648c..59e3337374 100644 --- a/src/app/(main)/community/events/page.tsx +++ b/src/app/(main)/community/events/page.tsx @@ -2,6 +2,9 @@ import dynamic from "next/dynamic" import { Breadcrumbs } from "@/_design-system/breadcrumbs" import { Button } from "@/app/conf/_design-system/button" +import { NavbarFixed } from "@/components/navbar/navbar-fixed" +import { TocHero, TocHeroContents } from "@/components/toc-hero" +import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" import { MeetupsMap } from "./meetups-map" import { EventsList } from "./events-list" @@ -10,6 +13,7 @@ import { GetYourMeetupNoticedSection } from "./get-your-meetup-noticed-section" import { BringGraphQLToYourCommunity } from "./bring-graphql-to-your-community" import { getAllEvents } from "./get-all-events" import { SubscribeToRssLink } from "./subscribe-to-rss-link" +import blurBean from "./events-blur-bean.webp" const ISSUE_TEMPLATE_LINK = "https://github.com/graphql/community-wg/issues/new?assignees=&labels=event&template=event-submission.yml" @@ -26,85 +30,135 @@ export default async function EventsPage() { const { upcomingEvents, pastEvents } = await getAllEvents() return ( -
-

Events & Meetups

- -
- + + } + > + + -
+ +
+
+ +
- {upcomingEvents.length > 0 && ( -
-
-
-

Upcoming events

-

- See what’s coming up across the GraphQL ecosystem. -

-
- +
+ + + + - - - - - -
- )} +
+ )} - + -
-

Meetups

-

- Find and join local GraphQL meetups happening around the world. Select - a city to explore upcoming events. -

+
+

Meetups

+

+ Find and join local GraphQL meetups happening around the world. + Select a city to explore upcoming events. +

+ + +
- -
+
+

Past events & meetups

+

+ A look back at how the GraphQL community connects and grows + together. +

+ +
-
-

Past events & meetups

-

- A look back at how the GraphQL community connects and grows together. +

Event gallery

+

+ A look back at what’s been happening.

- -
+ -

Event gallery

-

- A look back at what’s been happening. -

- + + +

+ + ) +} - - +function Stripes() { + return ( +
+
) } diff --git a/src/components/toc-hero/index.tsx b/src/components/toc-hero/index.tsx index 872069ac03..b9f20bf63c 100644 --- a/src/components/toc-hero/index.tsx +++ b/src/components/toc-hero/index.tsx @@ -8,9 +8,9 @@ export interface TocHeroProps { } export function TocHero({ heading, text, children, decoration }: TocHeroProps) { return ( -
+
{decoration} -
+

{heading}

{text}

{children} diff --git a/src/components/toc-hero/toc-hero-contents.tsx b/src/components/toc-hero/toc-hero-contents.tsx index f8d75d1d7c..f621002191 100644 --- a/src/components/toc-hero/toc-hero-contents.tsx +++ b/src/components/toc-hero/toc-hero-contents.tsx @@ -1,35 +1,55 @@ -import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr" +import { clsx } from "clsx" + import { ChevronRight } from "@/app/conf/_design-system/pixelarticons/chevron-right" export interface TocHeroContentsProps extends React.HTMLAttributes { - sections: string[] + sections: (string | { name: string; href: string })[] } export function TocHeroContents({ - sections: sections, + sections, + className, ...rest }: TocHeroContentsProps) { return (

What will you find here?

-
    - {sections.map((name, i) => ( -
  • - - - {name} - -
  • - ))} +
      + {sections.map((section, i) => { + const { name, href } = + typeof section === "string" + ? { + name: section, + href: `#${section.toLowerCase().replace(/ /g, "-")}`, + } + : section + + return ( +
    • + + + {name} + +
    • + ) + })}
) diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 293d287c4b..c3c9883ef9 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -21,6 +21,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' From 3b99e161ed4237a6ad456a9422c9db0d2a7724af Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 20:56:47 +0100 Subject: [PATCH 14/58] Add TeaserSection --- src/app/(main)/community/events/page.tsx | 2 +- src/components/learn-aggregator/index.tsx | 34 ++++++++++++++++++++--- src/pages/learn/index.mdx | 14 +++++++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/app/(main)/community/events/page.tsx b/src/app/(main)/community/events/page.tsx index 59e3337374..7f3bb6afff 100644 --- a/src/app/(main)/community/events/page.tsx +++ b/src/app/(main)/community/events/page.tsx @@ -37,7 +37,7 @@ export default async function EventsPage() { text="Connect with the GraphQL community through events and meetups around the world." decoration={} > -
+export interface TeaserSectionProps { + eyebrow: string + title: string + description: string + cta: ReactNode +} +export function TeaserSection({ + eyebrow, + title, + description, + cta, +}: TeaserSectionProps) { + return ( +
+
+
+ {eyebrow} +

{title}

+

+ {description} +

+ {cta} +
+
+
    +
    + ) } export function LearnHeroStripes() { @@ -12,7 +38,7 @@ export function LearnHeroStripes() {
    } > - + + Start learning + + } +/> + From 827bb14fd6a86f0624e2821bd80190ccd96f43dc Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 21:01:45 +0100 Subject: [PATCH 15/58] wip --- src/pages/learn/index.mdx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 7a96fc1370..220a20659c 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -37,3 +37,14 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' } /> + + Explore all best practices + + } +/> From 456a68a138efe57e293a1ed76c005d7534cf6d3c Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 21:11:26 +0100 Subject: [PATCH 16/58] wip --- src/components/learn-aggregator/index.tsx | 39 +++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 18628010cd..212231f9d8 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -1,20 +1,27 @@ +import { ReactNode } from "react" + import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" +import { Eyebrow } from "@/_design-system/eyebrow" import blurBean from "./learn-blur-bean.webp" -import { Eyebrow } from "@/_design-system/eyebrow" -import { ReactNode } from "react" export interface TeaserSectionProps { eyebrow: string title: string description: string cta: ReactNode + items: Array<{ + title: string + description: string + href: string + }> } export function TeaserSection({ eyebrow, title, description, cta, + items, }: TeaserSectionProps) { return (
    @@ -28,11 +35,37 @@ export function TeaserSection({ {cta}
    -
      +
        + {items.map((item, index) => { + return ( + + ) + })} +
      ) } +// https://www.figma.com/design/aPUvZDSxJfYDJtPd7GF2sB/GraphQL.org--Working-File?node-id=6368-6983&t=JE1eYbp6gpQRUILY-4 +// https://www.figma.com/design/aPUvZDSxJfYDJtPd7GF2sB/GraphQL.org--Working-File?node-id=5830-51637&t=JE1eYbp6gpQRUILY-4 +interface TeaserSectionListItemProps { + number: number + title: string + description: string +} +function TeaserSectionListItem({ + number, + title, + description, +}: TeaserSectionListItemProps) { + return
    • +} + export function LearnHeroStripes() { return (
      Date: Wed, 26 Nov 2025 21:22:58 +0100 Subject: [PATCH 17/58] wip --- src/components/learn-aggregator/index.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 212231f9d8..48141bab8c 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -2,6 +2,7 @@ import { ReactNode } from "react" import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" import { Eyebrow } from "@/_design-system/eyebrow" +import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" import blurBean from "./learn-blur-bean.webp" @@ -63,7 +64,19 @@ function TeaserSectionListItem({ title, description, }: TeaserSectionListItemProps) { - return
    • + return ( +
    • +
      +
      +

      + {description} +

      +
      +
      + +
      +
    • + ) } export function LearnHeroStripes() { From 365270ef4254db9c8fc840c8f62ec791fdfd9abb Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 21:39:40 +0100 Subject: [PATCH 18/58] Lazy load icons --- .../learn-aggregator/icons/board.svg | 1 + .../learn-aggregator/icons/books.svg | 1 + .../learn-aggregator/icons/cog-double.svg | 1 + .../learn-aggregator/icons/computer.svg | 1 + .../learn-aggregator/icons/construction.svg | 1 + src/components/learn-aggregator/icons/dna.svg | 1 + .../learn-aggregator/icons/globe.svg | 1 + .../learn-aggregator/icons/hierarchy.svg | 1 + src/components/learn-aggregator/icons/key.svg | 1 + .../learn-aggregator/icons/layer.svg | 1 + .../learn-aggregator/icons/menu.svg | 1 + .../icons/nav-left-circle.svg | 1 + .../learn-aggregator/icons/note.svg | 1 + .../learn-aggregator/icons/product-check.svg | 1 + .../learn-aggregator/icons/safe.svg | 1 + .../learn-aggregator/icons/search.svg | 1 + .../learn-aggregator/icons/share.svg | 1 + .../learn-aggregator/icons/solve.svg | 1 + .../learn-aggregator/icons/startup.svg | 1 + .../learn-aggregator/icons/sync-square.svg | 1 + .../learn-aggregator/icons/zoom-page.svg | 1 + src/components/learn-aggregator/index.tsx | 27 ++++++++++++++----- 22 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/components/learn-aggregator/icons/board.svg create mode 100644 src/components/learn-aggregator/icons/books.svg create mode 100644 src/components/learn-aggregator/icons/cog-double.svg create mode 100644 src/components/learn-aggregator/icons/computer.svg create mode 100644 src/components/learn-aggregator/icons/construction.svg create mode 100644 src/components/learn-aggregator/icons/dna.svg create mode 100644 src/components/learn-aggregator/icons/globe.svg create mode 100644 src/components/learn-aggregator/icons/hierarchy.svg create mode 100644 src/components/learn-aggregator/icons/key.svg create mode 100644 src/components/learn-aggregator/icons/layer.svg create mode 100644 src/components/learn-aggregator/icons/menu.svg create mode 100644 src/components/learn-aggregator/icons/nav-left-circle.svg create mode 100644 src/components/learn-aggregator/icons/note.svg create mode 100644 src/components/learn-aggregator/icons/product-check.svg create mode 100644 src/components/learn-aggregator/icons/safe.svg create mode 100644 src/components/learn-aggregator/icons/search.svg create mode 100644 src/components/learn-aggregator/icons/share.svg create mode 100644 src/components/learn-aggregator/icons/solve.svg create mode 100644 src/components/learn-aggregator/icons/startup.svg create mode 100644 src/components/learn-aggregator/icons/sync-square.svg create mode 100644 src/components/learn-aggregator/icons/zoom-page.svg diff --git a/src/components/learn-aggregator/icons/board.svg b/src/components/learn-aggregator/icons/board.svg new file mode 100644 index 0000000000..df7625bffe --- /dev/null +++ b/src/components/learn-aggregator/icons/board.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/books.svg b/src/components/learn-aggregator/icons/books.svg new file mode 100644 index 0000000000..b28d4f9656 --- /dev/null +++ b/src/components/learn-aggregator/icons/books.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/cog-double.svg b/src/components/learn-aggregator/icons/cog-double.svg new file mode 100644 index 0000000000..a169230ab5 --- /dev/null +++ b/src/components/learn-aggregator/icons/cog-double.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/computer.svg b/src/components/learn-aggregator/icons/computer.svg new file mode 100644 index 0000000000..49980390b9 --- /dev/null +++ b/src/components/learn-aggregator/icons/computer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/construction.svg b/src/components/learn-aggregator/icons/construction.svg new file mode 100644 index 0000000000..87ea57c465 --- /dev/null +++ b/src/components/learn-aggregator/icons/construction.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/dna.svg b/src/components/learn-aggregator/icons/dna.svg new file mode 100644 index 0000000000..4914769413 --- /dev/null +++ b/src/components/learn-aggregator/icons/dna.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/globe.svg b/src/components/learn-aggregator/icons/globe.svg new file mode 100644 index 0000000000..17f6cb543d --- /dev/null +++ b/src/components/learn-aggregator/icons/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/hierarchy.svg b/src/components/learn-aggregator/icons/hierarchy.svg new file mode 100644 index 0000000000..f907687b01 --- /dev/null +++ b/src/components/learn-aggregator/icons/hierarchy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/key.svg b/src/components/learn-aggregator/icons/key.svg new file mode 100644 index 0000000000..a5792cc894 --- /dev/null +++ b/src/components/learn-aggregator/icons/key.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/layer.svg b/src/components/learn-aggregator/icons/layer.svg new file mode 100644 index 0000000000..54b7bb9542 --- /dev/null +++ b/src/components/learn-aggregator/icons/layer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/menu.svg b/src/components/learn-aggregator/icons/menu.svg new file mode 100644 index 0000000000..2fc41369cb --- /dev/null +++ b/src/components/learn-aggregator/icons/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/nav-left-circle.svg b/src/components/learn-aggregator/icons/nav-left-circle.svg new file mode 100644 index 0000000000..3b568b6fdd --- /dev/null +++ b/src/components/learn-aggregator/icons/nav-left-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/note.svg b/src/components/learn-aggregator/icons/note.svg new file mode 100644 index 0000000000..39e0de7c52 --- /dev/null +++ b/src/components/learn-aggregator/icons/note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/product-check.svg b/src/components/learn-aggregator/icons/product-check.svg new file mode 100644 index 0000000000..046554e4cd --- /dev/null +++ b/src/components/learn-aggregator/icons/product-check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/safe.svg b/src/components/learn-aggregator/icons/safe.svg new file mode 100644 index 0000000000..93f832daee --- /dev/null +++ b/src/components/learn-aggregator/icons/safe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/search.svg b/src/components/learn-aggregator/icons/search.svg new file mode 100644 index 0000000000..c52d9f08b7 --- /dev/null +++ b/src/components/learn-aggregator/icons/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/share.svg b/src/components/learn-aggregator/icons/share.svg new file mode 100644 index 0000000000..6567793f34 --- /dev/null +++ b/src/components/learn-aggregator/icons/share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/solve.svg b/src/components/learn-aggregator/icons/solve.svg new file mode 100644 index 0000000000..0479304299 --- /dev/null +++ b/src/components/learn-aggregator/icons/solve.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/startup.svg b/src/components/learn-aggregator/icons/startup.svg new file mode 100644 index 0000000000..ee982cf48f --- /dev/null +++ b/src/components/learn-aggregator/icons/startup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/sync-square.svg b/src/components/learn-aggregator/icons/sync-square.svg new file mode 100644 index 0000000000..1931355fad --- /dev/null +++ b/src/components/learn-aggregator/icons/sync-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/icons/zoom-page.svg b/src/components/learn-aggregator/icons/zoom-page.svg new file mode 100644 index 0000000000..9680c94c26 --- /dev/null +++ b/src/components/learn-aggregator/icons/zoom-page.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 48141bab8c..d1fcb2beca 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -15,7 +15,9 @@ export interface TeaserSectionProps { title: string description: string href: string + icon: string }> + firstIconsEager?: boolean } export function TeaserSection({ eyebrow, @@ -23,6 +25,7 @@ export function TeaserSection({ description, cta, items, + firstIconsEager, }: TeaserSectionProps) { return (
      @@ -44,6 +47,16 @@ export function TeaserSection({ number={index + 1} title={item.title} description={item.description} + icon={ + + } /> ) })} @@ -58,20 +71,22 @@ interface TeaserSectionListItemProps { number: number title: string description: string + icon: ReactNode } function TeaserSectionListItem({ number, title, description, + icon, }: TeaserSectionListItemProps) { return (
    • -
      -
      -

      - {description} -

      -
      + {icon} + Lesson {number} + {title} +

      + {description} +

      From 4a1a7dab5bc0b713993801f8fcd7e16bf9c4f87e Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 21:40:07 +0100 Subject: [PATCH 19/58] Add firstIconsEager=true to first section --- src/pages/learn/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 220a20659c..7f1e58ea24 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -35,6 +35,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' Start learning } + firstIconsEager /> Date: Wed, 26 Nov 2025 22:01:23 +0100 Subject: [PATCH 20/58] wip --- src/components/learn-aggregator/items.tsx | 156 ++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/components/learn-aggregator/items.tsx diff --git a/src/components/learn-aggregator/items.tsx b/src/components/learn-aggregator/items.tsx new file mode 100644 index 0000000000..248cc78b89 --- /dev/null +++ b/src/components/learn-aggregator/items.tsx @@ -0,0 +1,156 @@ +import meta from "../../pages/learn/_meta" + +type LearnPagePath = Exclude + +function getTitle(path: LearnPagePath): string { + const entry = meta[path as keyof typeof meta] + if (typeof entry === "string") { + return ( + entry || path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) + ) + } else if (typeof entry === "object" && "title" in entry) { + return entry.title + } + return path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) +} + +export const learnPages: Record< + LearnPagePath, + { + title: string + description: string + icon: string + section: "getting-started" | "best-practices" + } | null +> = { + introduction: { + title: getTitle("introduction"), + description: "", + icon: "", + section: "getting-started", + }, + schema: { + title: getTitle("schema"), + description: "", + icon: "", + section: "getting-started", + }, + queries: { + title: getTitle("queries"), + description: "", + icon: "", + section: "getting-started", + }, + mutations: { + title: getTitle("mutations"), + description: "", + icon: "", + section: "getting-started", + }, + subscriptions: { + title: getTitle("subscriptions"), + description: "", + icon: "", + section: "getting-started", + }, + validation: { + title: getTitle("validation"), + description: "", + icon: "", + section: "getting-started", + }, + execution: { + title: getTitle("execution"), + description: "", + icon: "", + section: "getting-started", + }, + response: { + title: getTitle("response"), + description: "", + icon: "", + section: "getting-started", + }, + introspection: { + title: getTitle("introspection"), + description: "", + icon: "", + section: "getting-started", + }, + // --- + "best-practices": { + title: getTitle("best-practices"), + description: "", + icon: "", + section: "best-practices", + }, + "thinking-in-graphs": { + title: getTitle("thinking-in-graphs"), + description: "", + icon: "", + section: "best-practices", + }, + "serving-over-http": { + title: getTitle("serving-over-http"), + description: "", + icon: "", + section: "best-practices", + }, + "file-uploads": { + title: getTitle("file-uploads"), + description: "", + icon: "", + section: "best-practices", + }, + authorization: { + title: getTitle("authorization"), + description: "", + icon: "", + section: "best-practices", + }, + pagination: { + title: getTitle("pagination"), + description: "", + icon: "", + section: "best-practices", + }, + "schema-design": { + title: getTitle("schema-design"), + description: "", + icon: "", + section: "best-practices", + }, + "global-object-identification": { + title: getTitle("global-object-identification"), + description: "", + icon: "", + section: "best-practices", + }, + caching: { + title: getTitle("caching"), + description: "", + icon: "", + section: "best-practices", + }, + performance: { + title: getTitle("performance"), + description: "", + icon: "", + section: "best-practices", + }, + security: { + title: getTitle("security"), + description: "", + icon: "", + section: "best-practices", + }, + federation: { + title: getTitle("federation"), + description: "", + icon: "", + section: "best-practices", + }, + // --- + // omitted on Learn index page + "debug-errors": null, +} From 18650f2947014a8de30548db65014b615c37fba2 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:05:50 +0100 Subject: [PATCH 21/58] wip --- src/components/learn-aggregator/items.tsx | 64 +++++++++-------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/src/components/learn-aggregator/items.tsx b/src/components/learn-aggregator/items.tsx index 248cc78b89..ecd354c8d5 100644 --- a/src/components/learn-aggregator/items.tsx +++ b/src/components/learn-aggregator/items.tsx @@ -2,150 +2,116 @@ import meta from "../../pages/learn/_meta" type LearnPagePath = Exclude -function getTitle(path: LearnPagePath): string { - const entry = meta[path as keyof typeof meta] - if (typeof entry === "string") { - return ( - entry || path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) - ) - } else if (typeof entry === "object" && "title" in entry) { - return entry.title - } - return path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) +interface LearnPageItem { + title: string + description: string + icon: string + section: "getting-started" | "best-practices" } -export const learnPages: Record< - LearnPagePath, - { - title: string - description: string - icon: string - section: "getting-started" | "best-practices" - } | null -> = { +const _items: Record | null> = { introduction: { - title: getTitle("introduction"), description: "", icon: "", section: "getting-started", }, schema: { - title: getTitle("schema"), description: "", icon: "", section: "getting-started", }, queries: { - title: getTitle("queries"), description: "", icon: "", section: "getting-started", }, mutations: { - title: getTitle("mutations"), description: "", icon: "", section: "getting-started", }, subscriptions: { - title: getTitle("subscriptions"), description: "", icon: "", section: "getting-started", }, validation: { - title: getTitle("validation"), description: "", icon: "", section: "getting-started", }, execution: { - title: getTitle("execution"), description: "", icon: "", section: "getting-started", }, response: { - title: getTitle("response"), description: "", icon: "", section: "getting-started", }, introspection: { - title: getTitle("introspection"), description: "", icon: "", section: "getting-started", }, // --- "best-practices": { - title: getTitle("best-practices"), description: "", icon: "", section: "best-practices", }, "thinking-in-graphs": { - title: getTitle("thinking-in-graphs"), description: "", icon: "", section: "best-practices", }, "serving-over-http": { - title: getTitle("serving-over-http"), description: "", icon: "", section: "best-practices", }, "file-uploads": { - title: getTitle("file-uploads"), description: "", icon: "", section: "best-practices", }, authorization: { - title: getTitle("authorization"), description: "", icon: "", section: "best-practices", }, pagination: { - title: getTitle("pagination"), description: "", icon: "", section: "best-practices", }, "schema-design": { - title: getTitle("schema-design"), description: "", icon: "", section: "best-practices", }, "global-object-identification": { - title: getTitle("global-object-identification"), description: "", icon: "", section: "best-practices", }, caching: { - title: getTitle("caching"), description: "", icon: "", section: "best-practices", }, performance: { - title: getTitle("performance"), description: "", icon: "", section: "best-practices", }, security: { - title: getTitle("security"), description: "", icon: "", section: "best-practices", }, federation: { - title: getTitle("federation"), description: "", icon: "", section: "best-practices", @@ -154,3 +120,21 @@ export const learnPages: Record< // omitted on Learn index page "debug-errors": null, } + +export const learnPages = _items as Record + +for (const path in learnPages) { + const page = learnPages[path as LearnPagePath] + if (page === null) continue + const metaEntry = meta[path as keyof typeof meta] + + if (typeof metaEntry === "string") { + page.title = + metaEntry || + path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) + } else if (typeof metaEntry === "object" && "title" in metaEntry) { + page.title = metaEntry.title + } else { + page.title = path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) + } +} From c710ef2c8ea8fbde6e0092c817ce4c4cf07948b1 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:07:16 +0100 Subject: [PATCH 22/58] wip --- src/components/learn-aggregator/items.tsx | 8 +++++--- src/pages/learn/_meta.ts | 4 ---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/learn-aggregator/items.tsx b/src/components/learn-aggregator/items.tsx index ecd354c8d5..16749c9f75 100644 --- a/src/components/learn-aggregator/items.tsx +++ b/src/components/learn-aggregator/items.tsx @@ -116,9 +116,11 @@ const _items: Record | null> = { icon: "", section: "best-practices", }, - // --- - // omitted on Learn index page - "debug-errors": null, + "debug-errors": { + description: "", + icon: "", + section: "best-practices", + }, } export const learnPages = _items as Record diff --git a/src/pages/learn/_meta.ts b/src/pages/learn/_meta.ts index 32df28adc8..29048f6fac 100644 --- a/src/pages/learn/_meta.ts +++ b/src/pages/learn/_meta.ts @@ -37,9 +37,5 @@ export default { performance: "", security: "", federation: "", - "-- 3": { - type: "separator", - title: "GraphQL over HTTP", - }, "debug-errors": "Common GraphQL over HTTP Errors", } From 77febbb0fa8451dab5a7f9b6cbe1085fadb77278 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:11:48 +0100 Subject: [PATCH 23/58] wip --- src/components/learn-aggregator/items.tsx | 110 +++++++++++++--------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/src/components/learn-aggregator/items.tsx b/src/components/learn-aggregator/items.tsx index 16749c9f75..a0fb742cfa 100644 --- a/src/components/learn-aggregator/items.tsx +++ b/src/components/learn-aggregator/items.tsx @@ -11,114 +11,136 @@ interface LearnPageItem { const _items: Record | null> = { introduction: { - description: "", - icon: "", + description: + "Get a high-level overview of GraphQL and how it enables flexible, versionless APIs powered by a strong type system.", + icon: new URL("./icons/computer.svg", import.meta.url).href, section: "getting-started", }, schema: { - description: "", - icon: "", + description: + "Learn the elements of the GraphQL type system and how schemas describe your data and relationships.", + icon: new URL("./icons/hierarchy.svg", import.meta.url).href, section: "getting-started", }, queries: { - description: "", - icon: "", + description: + "Use query operations to fetch exactly the data you need from a GraphQL server.", + icon: new URL("./icons/search.svg", import.meta.url).href, section: "getting-started", }, mutations: { - description: "", - icon: "", + description: + "See how mutation operations write data and when side effects are allowed in GraphQL.", + icon: new URL("./icons/construction.svg", import.meta.url).href, section: "getting-started", }, subscriptions: { - description: "", - icon: "", + description: + "Get real-time updates from a GraphQL server with long-lived subscription operations.", + icon: new URL("./icons/sync-square.svg", import.meta.url).href, section: "getting-started", }, validation: { - description: "", - icon: "", + description: + "Validate operations against your schema to catch issues before execution.", + icon: new URL("./icons/product-check.svg", import.meta.url).href, section: "getting-started", }, execution: { - description: "", - icon: "", + description: + "Understand how GraphQL resolves fields during execution to fulfill client requests.", + icon: new URL("./icons/board.svg", import.meta.url).href, section: "getting-started", }, response: { - description: "", - icon: "", + description: + "Learn how GraphQL responses mirror queries, include data, and surface errors.", + icon: new URL("./icons/share.svg", import.meta.url).href, section: "getting-started", }, introspection: { - description: "", - icon: "", + description: + "Ask a schema about its types and fields using GraphQL's introspection system.", + icon: new URL("./icons/zoom-page.svg", import.meta.url).href, section: "getting-started", }, // --- "best-practices": { - description: "", - icon: "", + description: + "Practical guidance for networking, authorization, pagination, and other everyday GraphQL concerns.", + icon: new URL("./icons/books.svg", import.meta.url).href, section: "best-practices", }, "thinking-in-graphs": { - description: "", - icon: "", + description: + "Model your business domain as a graph and use schemas to express connected types.", + icon: new URL("./icons/layer.svg", import.meta.url).href, section: "best-practices", }, "serving-over-http": { - description: "", - icon: "", + description: + "Follow HTTP guidelines to respond to GraphQL queries and mutations over the web.", + icon: new URL("./icons/globe.svg", import.meta.url).href, section: "best-practices", }, "file-uploads": { - description: "", - icon: "", + description: + "Understand why file uploads are tricky in GraphQL and safer patterns to support them.", + icon: new URL("./icons/note.svg", import.meta.url).href, section: "best-practices", }, authorization: { - description: "", - icon: "", + description: + "Design authorization in your schema to control which users can access specific data.", + icon: new URL("./icons/key.svg", import.meta.url).href, section: "best-practices", }, pagination: { - description: "", - icon: "", + description: + "Paginate lists and connections so clients can traverse large graphs efficiently.", + icon: new URL("./icons/menu.svg", import.meta.url).href, section: "best-practices", }, "schema-design": { - description: "", - icon: "", + description: + "Evolve schemas without versioning while keeping types clear and future-friendly.", + icon: new URL("./icons/cog-double.svg", import.meta.url).href, section: "best-practices", }, "global-object-identification": { - description: "", - icon: "", + description: + "Expose global object IDs so clients can refetch, cache, and reference data reliably.", + icon: new URL("./icons/dna.svg", import.meta.url).href, section: "best-practices", }, caching: { - description: "", - icon: "", + description: + "Use identifiers and response patterns that enable effective caching for GraphQL clients and servers.", + icon: new URL("./icons/sync-square.svg", import.meta.url).href, section: "best-practices", }, performance: { - description: "", - icon: "", + description: + "Optimize GraphQL requests and implementations for fast, efficient performance.", + icon: new URL("./icons/startup.svg", import.meta.url).href, section: "best-practices", }, security: { - description: "", - icon: "", + description: + "Protect GraphQL APIs against common attack vectors with layered security practices.", + icon: new URL("./icons/safe.svg", import.meta.url).href, section: "best-practices", }, federation: { - description: "", - icon: "", + description: + "Compose multiple services into a single graph using GraphQL federation.", + icon: new URL("./icons/globe.svg", import.meta.url).href, section: "best-practices", }, "debug-errors": { - description: "", - icon: "", + description: + "Identify common HTTP and GraphQL errors and debug them effectively.", + icon: new URL("./icons/solve.svg", import.meta.url).href, section: "best-practices", }, } From 751f363df4e7b2aa910f452252f6f632a3cb2966 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:16:26 +0100 Subject: [PATCH 24/58] Use correct descriptions --- src/components/learn-aggregator/items.tsx | 42 +++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/components/learn-aggregator/items.tsx b/src/components/learn-aggregator/items.tsx index a0fb742cfa..06d3605829 100644 --- a/src/components/learn-aggregator/items.tsx +++ b/src/components/learn-aggregator/items.tsx @@ -18,128 +18,128 @@ const _items: Record | null> = { }, schema: { description: - "Learn the elements of the GraphQL type system and how schemas describe your data and relationships.", + "Learn how GraphQL’s schema language defines the shape of your data using types.", icon: new URL("./icons/hierarchy.svg", import.meta.url).href, section: "getting-started", }, queries: { description: - "Use query operations to fetch exactly the data you need from a GraphQL server.", + "Understand how to structure GraphQL queries to request exactly the data you need — including fields, variables and fragments.", icon: new URL("./icons/search.svg", import.meta.url).href, section: "getting-started", }, mutations: { description: - "See how mutation operations write data and when side effects are allowed in GraphQL.", + "Explore how to modify data with mutations, including how to update and remove records through your schema.", icon: new URL("./icons/construction.svg", import.meta.url).href, section: "getting-started", }, subscriptions: { description: - "Get real-time updates from a GraphQL server with long-lived subscription operations.", + "Discover how GraphQL supports real-time data with subscriptions and how to use them effectively at scale.", icon: new URL("./icons/sync-square.svg", import.meta.url).href, section: "getting-started", }, validation: { description: - "Validate operations against your schema to catch issues before execution.", + "See how GraphQL ensures query correctness through validation rules and how common errors are detected early.", icon: new URL("./icons/product-check.svg", import.meta.url).href, section: "getting-started", }, execution: { description: - "Understand how GraphQL resolves fields during execution to fulfill client requests.", + "Learn how resolvers power GraphQL execution and how the server processes and returns data for each query.", icon: new URL("./icons/board.svg", import.meta.url).href, section: "getting-started", }, response: { description: - "Learn how GraphQL responses mirror queries, include data, and surface errors.", + "Explore how GraphQL structures its responses, including data, errors and extensions for custom metadata.", icon: new URL("./icons/share.svg", import.meta.url).href, section: "getting-started", }, introspection: { description: - "Ask a schema about its types and fields using GraphQL's introspection system.", + "Use introspection to explore the schema itself — a powerful way to inspect types and fields dynamically.", icon: new URL("./icons/zoom-page.svg", import.meta.url).href, section: "getting-started", }, // --- "best-practices": { description: - "Practical guidance for networking, authorization, pagination, and other everyday GraphQL concerns.", + "Practical guidance for common GraphQL concerns like networking, authorization, and pagination.", icon: new URL("./icons/books.svg", import.meta.url).href, section: "best-practices", }, "thinking-in-graphs": { description: - "Model your business domain as a graph and use schemas to express connected types.", + "Learn how to shift your mindset from RESTful endpoints to graph-based thinking, aligning your schema with business logic and legacy systems.", icon: new URL("./icons/layer.svg", import.meta.url).href, section: "best-practices", }, "serving-over-http": { description: - "Follow HTTP guidelines to respond to GraphQL queries and mutations over the web.", + "Explore how GraphQL operates over HTTP, including methods, headers, status codes and API endpoint design.", icon: new URL("./icons/globe.svg", import.meta.url).href, section: "best-practices", }, "file-uploads": { description: - "Understand why file uploads are tricky in GraphQL and safer patterns to support them.", + "Handle file uploads in GraphQL by wrapping them as mutations. Learn the recommended approach for integrating file handling into your API.", icon: new URL("./icons/note.svg", import.meta.url).href, section: "best-practices", }, authorization: { description: - "Design authorization in your schema to control which users can access specific data.", + "Understand how to secure your GraphQL APIs with type- and field-level authorization patterns.", icon: new URL("./icons/key.svg", import.meta.url).href, section: "best-practices", }, pagination: { description: - "Paginate lists and connections so clients can traverse large graphs efficiently.", + "Discover different pagination strategies in GraphQL, from simple slicing to fully connected edges and nodes.", icon: new URL("./icons/menu.svg", import.meta.url).href, section: "best-practices", }, "schema-design": { description: - "Evolve schemas without versioning while keeping types clear and future-friendly.", + "Learn how to design clear, adaptable schemas — including versioning and thoughtful use of nullability.", icon: new URL("./icons/cog-double.svg", import.meta.url).href, section: "best-practices", }, "global-object-identification": { description: - "Expose global object IDs so clients can refetch, cache, and reference data reliably.", + "Use globally unique IDs and the Node interface to enable caching, refetching, and efficient schema traversal.", icon: new URL("./icons/dna.svg", import.meta.url).href, section: "best-practices", }, caching: { description: - "Use identifiers and response patterns that enable effective caching for GraphQL clients and servers.", + "Explore caching techniques and ID strategies that make client-side performance and object reuse more effective.", icon: new URL("./icons/sync-square.svg", import.meta.url).href, section: "best-practices", }, performance: { description: - "Optimize GraphQL requests and implementations for fast, efficient performance.", + "Get practical tips for improving GraphQL performance — from preventing N+1 problems to monitoring and compression.", icon: new URL("./icons/startup.svg", import.meta.url).href, section: "best-practices", }, security: { description: - "Protect GraphQL APIs against common attack vectors with layered security practices.", + "Protect your GraphQL API with best practices for query limits, input validation, introspection control and more.", icon: new URL("./icons/safe.svg", import.meta.url).href, section: "best-practices", }, federation: { description: - "Compose multiple services into a single graph using GraphQL federation.", + "Learn how GraphQL federation enables modular, scalable APIs by composing services into a unified schema.", icon: new URL("./icons/globe.svg", import.meta.url).href, section: "best-practices", }, "debug-errors": { description: - "Identify common HTTP and GraphQL errors and debug them effectively.", + "Learn about common 'graphql-http' errors and how to debug them.", icon: new URL("./icons/solve.svg", import.meta.url).href, section: "best-practices", }, From e440aca80ce3f791f0be252943744a25a9f1afb4 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:20:19 +0100 Subject: [PATCH 25/58] Add icon backgrounds --- src/components/learn-aggregator/index.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index d1fcb2beca..f33e9c5c6b 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -5,6 +5,7 @@ import { Eyebrow } from "@/_design-system/eyebrow" import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" import blurBean from "./learn-blur-bean.webp" +import clsx from "clsx" export interface TeaserSectionProps { eyebrow: string @@ -72,19 +73,29 @@ interface TeaserSectionListItemProps { title: string description: string icon: ReactNode + section: "getting-started" | "best-practices" } function TeaserSectionListItem({ number, title, description, icon, + section, }: TeaserSectionListItemProps) { return (
    • - {icon} +
      + {icon} +
      Lesson {number} - {title} -

      + {title} +

      {description}

      From 4390e4012f815db7a8a3cfe6d0634cde171e97ee Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:24:35 +0100 Subject: [PATCH 26/58] Card layout --- src/components/learn-aggregator/index.tsx | 55 ++++++++++++++++------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index f33e9c5c6b..112d41c065 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -17,6 +17,7 @@ export interface TeaserSectionProps { description: string href: string icon: string + section: "getting-started" | "best-practices" }> firstIconsEager?: boolean } @@ -48,6 +49,8 @@ export function TeaserSection({ number={index + 1} title={item.title} description={item.description} + href={item.href} + section={item.section} icon={ - - Lesson {number} - {title} -

      - {description} -

      -
      - -
      +
      + {icon} +
      + +
      + + Lesson {number} + + + {title} + +
      + +

      + {description} +

      + +
      + +
      +
    • ) } From dfe67afb868794aa59bbcf9729fd62223888a0f0 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Wed, 26 Nov 2025 22:37:40 +0100 Subject: [PATCH 27/58] Partition by section --- .../{items.tsx => learn-pages.tsx} | 16 +++++++++++++++- src/pages/learn/index.mdx | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) rename src/components/learn-aggregator/{items.tsx => learn-pages.tsx} (95%) diff --git a/src/components/learn-aggregator/items.tsx b/src/components/learn-aggregator/learn-pages.tsx similarity index 95% rename from src/components/learn-aggregator/items.tsx rename to src/components/learn-aggregator/learn-pages.tsx index 06d3605829..7d950eff87 100644 --- a/src/components/learn-aggregator/items.tsx +++ b/src/components/learn-aggregator/learn-pages.tsx @@ -7,9 +7,13 @@ interface LearnPageItem { description: string icon: string section: "getting-started" | "best-practices" + href: string } -const _items: Record | null> = { +const _items: Record< + LearnPagePath, + Omit | null +> = { introduction: { description: "Get a high-level overview of GraphQL and how it enables flexible, versionless APIs powered by a strong type system.", @@ -147,6 +151,12 @@ const _items: Record | null> = { export const learnPages = _items as Record +export const pagesBySection: Record = + { + "getting-started": [], + "best-practices": [], + } + for (const path in learnPages) { const page = learnPages[path as LearnPagePath] if (page === null) continue @@ -161,4 +171,8 @@ for (const path in learnPages) { } else { page.title = path.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()) } + + page.href = `/learn/${path}` + + pagesBySection[page.section].push(page) } diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 7f1e58ea24..0d361057de 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -2,6 +2,7 @@ import { Button } from '@/app/conf/_design-system/button'; import { TocHero, TocHeroContents } from '../../components/toc-hero'; import { TeaserSection, LearnHeroStripes } from '../../components/learn-aggregator' +import { pagesBySection } from '../../components/learn-aggregator/learn-pages' import { NavbarFixed } from '../../components/navbar/navbar-fixed' @@ -36,6 +37,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' } firstIconsEager + items={pagesBySection["getting-started"]} /> } + items={pagesBySection["best-practices"]} /> From 4b9fea087d5be7bb27eb949d2b3aa9fe267f208a Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Thu, 27 Nov 2025 13:27:08 +0100 Subject: [PATCH 28/58] Improve styles --- src/components/learn-aggregator/index.tsx | 27 ++++++++++++------- .../learn-aggregator/learn-pages.tsx | 2 +- src/pages/learn/index.mdx | 4 ++- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 112d41c065..c726097728 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -7,7 +7,8 @@ import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.sv import blurBean from "./learn-blur-bean.webp" import clsx from "clsx" -export interface TeaserSectionProps { +export interface TeaserSectionProps + extends React.HTMLAttributes { eyebrow: string title: string description: string @@ -28,10 +29,18 @@ export function TeaserSection({ cta, items, firstIconsEager, + className, + ...rest }: TeaserSectionProps) { return ( -
      -
      +
      +
      {eyebrow}

      {title}

      @@ -41,7 +50,7 @@ export function TeaserSection({ {cta}
      -
        +
          {items.map((item, index) => { return ( -
      +
      ) } @@ -91,7 +100,7 @@ function TeaserSectionListItem({
    • -
      +
      Lesson {number} @@ -118,7 +127,7 @@ function TeaserSectionListItem({ {description}

      -
      +
      @@ -131,7 +140,7 @@ export function LearnHeroStripes() {
      - Date: Thu, 27 Nov 2025 13:28:49 +0100 Subject: [PATCH 29/58] wip --- src/components/learn-aggregator/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index c726097728..fd4e0a0eaf 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -104,7 +104,7 @@ function TeaserSectionListItem({ >
      -

      +

      {description}

      From 943f6206448fd8ad0b3ed4f5cb1090b98bc3036e Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Thu, 27 Nov 2025 14:30:25 +0100 Subject: [PATCH 30/58] Rename the icons directory to fix icons --- .../{icons => assets}/board.svg | 0 .../{icons => assets}/books.svg | 0 .../{icons/menu.svg => assets/checkbox.svg} | 0 .../{icons => assets}/cog-double.svg | 0 .../{icons => assets}/computer.svg | 0 .../{icons => assets}/construction.svg | 0 .../{icons => assets}/dna.svg | 0 .../{icons => assets}/globe.svg | 0 .../{icons => assets}/hierarchy.svg | 0 .../{icons => assets}/key.svg | 0 .../{icons => assets}/layer.svg | 0 .../{icons => assets}/nav-left-circle.svg | 0 .../{icons => assets}/note.svg | 0 .../{icons => assets}/product-check.svg | 0 .../{icons => assets}/safe.svg | 0 .../{icons => assets}/search.svg | 0 .../{icons => assets}/share.svg | 0 .../{icons => assets}/solve.svg | 0 .../{icons => assets}/startup.svg | 0 .../{icons => assets}/sync-square.svg | 0 .../{icons => assets}/zoom-page.svg | 0 src/components/learn-aggregator/index.tsx | 6 +-- .../learn-aggregator/learn-pages.tsx | 44 +++++++++---------- 23 files changed, 25 insertions(+), 25 deletions(-) rename src/components/learn-aggregator/{icons => assets}/board.svg (100%) rename src/components/learn-aggregator/{icons => assets}/books.svg (100%) rename src/components/learn-aggregator/{icons/menu.svg => assets/checkbox.svg} (100%) rename src/components/learn-aggregator/{icons => assets}/cog-double.svg (100%) rename src/components/learn-aggregator/{icons => assets}/computer.svg (100%) rename src/components/learn-aggregator/{icons => assets}/construction.svg (100%) rename src/components/learn-aggregator/{icons => assets}/dna.svg (100%) rename src/components/learn-aggregator/{icons => assets}/globe.svg (100%) rename src/components/learn-aggregator/{icons => assets}/hierarchy.svg (100%) rename src/components/learn-aggregator/{icons => assets}/key.svg (100%) rename src/components/learn-aggregator/{icons => assets}/layer.svg (100%) rename src/components/learn-aggregator/{icons => assets}/nav-left-circle.svg (100%) rename src/components/learn-aggregator/{icons => assets}/note.svg (100%) rename src/components/learn-aggregator/{icons => assets}/product-check.svg (100%) rename src/components/learn-aggregator/{icons => assets}/safe.svg (100%) rename src/components/learn-aggregator/{icons => assets}/search.svg (100%) rename src/components/learn-aggregator/{icons => assets}/share.svg (100%) rename src/components/learn-aggregator/{icons => assets}/solve.svg (100%) rename src/components/learn-aggregator/{icons => assets}/startup.svg (100%) rename src/components/learn-aggregator/{icons => assets}/sync-square.svg (100%) rename src/components/learn-aggregator/{icons => assets}/zoom-page.svg (100%) diff --git a/src/components/learn-aggregator/icons/board.svg b/src/components/learn-aggregator/assets/board.svg similarity index 100% rename from src/components/learn-aggregator/icons/board.svg rename to src/components/learn-aggregator/assets/board.svg diff --git a/src/components/learn-aggregator/icons/books.svg b/src/components/learn-aggregator/assets/books.svg similarity index 100% rename from src/components/learn-aggregator/icons/books.svg rename to src/components/learn-aggregator/assets/books.svg diff --git a/src/components/learn-aggregator/icons/menu.svg b/src/components/learn-aggregator/assets/checkbox.svg similarity index 100% rename from src/components/learn-aggregator/icons/menu.svg rename to src/components/learn-aggregator/assets/checkbox.svg diff --git a/src/components/learn-aggregator/icons/cog-double.svg b/src/components/learn-aggregator/assets/cog-double.svg similarity index 100% rename from src/components/learn-aggregator/icons/cog-double.svg rename to src/components/learn-aggregator/assets/cog-double.svg diff --git a/src/components/learn-aggregator/icons/computer.svg b/src/components/learn-aggregator/assets/computer.svg similarity index 100% rename from src/components/learn-aggregator/icons/computer.svg rename to src/components/learn-aggregator/assets/computer.svg diff --git a/src/components/learn-aggregator/icons/construction.svg b/src/components/learn-aggregator/assets/construction.svg similarity index 100% rename from src/components/learn-aggregator/icons/construction.svg rename to src/components/learn-aggregator/assets/construction.svg diff --git a/src/components/learn-aggregator/icons/dna.svg b/src/components/learn-aggregator/assets/dna.svg similarity index 100% rename from src/components/learn-aggregator/icons/dna.svg rename to src/components/learn-aggregator/assets/dna.svg diff --git a/src/components/learn-aggregator/icons/globe.svg b/src/components/learn-aggregator/assets/globe.svg similarity index 100% rename from src/components/learn-aggregator/icons/globe.svg rename to src/components/learn-aggregator/assets/globe.svg diff --git a/src/components/learn-aggregator/icons/hierarchy.svg b/src/components/learn-aggregator/assets/hierarchy.svg similarity index 100% rename from src/components/learn-aggregator/icons/hierarchy.svg rename to src/components/learn-aggregator/assets/hierarchy.svg diff --git a/src/components/learn-aggregator/icons/key.svg b/src/components/learn-aggregator/assets/key.svg similarity index 100% rename from src/components/learn-aggregator/icons/key.svg rename to src/components/learn-aggregator/assets/key.svg diff --git a/src/components/learn-aggregator/icons/layer.svg b/src/components/learn-aggregator/assets/layer.svg similarity index 100% rename from src/components/learn-aggregator/icons/layer.svg rename to src/components/learn-aggregator/assets/layer.svg diff --git a/src/components/learn-aggregator/icons/nav-left-circle.svg b/src/components/learn-aggregator/assets/nav-left-circle.svg similarity index 100% rename from src/components/learn-aggregator/icons/nav-left-circle.svg rename to src/components/learn-aggregator/assets/nav-left-circle.svg diff --git a/src/components/learn-aggregator/icons/note.svg b/src/components/learn-aggregator/assets/note.svg similarity index 100% rename from src/components/learn-aggregator/icons/note.svg rename to src/components/learn-aggregator/assets/note.svg diff --git a/src/components/learn-aggregator/icons/product-check.svg b/src/components/learn-aggregator/assets/product-check.svg similarity index 100% rename from src/components/learn-aggregator/icons/product-check.svg rename to src/components/learn-aggregator/assets/product-check.svg diff --git a/src/components/learn-aggregator/icons/safe.svg b/src/components/learn-aggregator/assets/safe.svg similarity index 100% rename from src/components/learn-aggregator/icons/safe.svg rename to src/components/learn-aggregator/assets/safe.svg diff --git a/src/components/learn-aggregator/icons/search.svg b/src/components/learn-aggregator/assets/search.svg similarity index 100% rename from src/components/learn-aggregator/icons/search.svg rename to src/components/learn-aggregator/assets/search.svg diff --git a/src/components/learn-aggregator/icons/share.svg b/src/components/learn-aggregator/assets/share.svg similarity index 100% rename from src/components/learn-aggregator/icons/share.svg rename to src/components/learn-aggregator/assets/share.svg diff --git a/src/components/learn-aggregator/icons/solve.svg b/src/components/learn-aggregator/assets/solve.svg similarity index 100% rename from src/components/learn-aggregator/icons/solve.svg rename to src/components/learn-aggregator/assets/solve.svg diff --git a/src/components/learn-aggregator/icons/startup.svg b/src/components/learn-aggregator/assets/startup.svg similarity index 100% rename from src/components/learn-aggregator/icons/startup.svg rename to src/components/learn-aggregator/assets/startup.svg diff --git a/src/components/learn-aggregator/icons/sync-square.svg b/src/components/learn-aggregator/assets/sync-square.svg similarity index 100% rename from src/components/learn-aggregator/icons/sync-square.svg rename to src/components/learn-aggregator/assets/sync-square.svg diff --git a/src/components/learn-aggregator/icons/zoom-page.svg b/src/components/learn-aggregator/assets/zoom-page.svg similarity index 100% rename from src/components/learn-aggregator/icons/zoom-page.svg rename to src/components/learn-aggregator/assets/zoom-page.svg diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index fd4e0a0eaf..d5bea077f0 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -104,7 +104,7 @@ function TeaserSectionListItem({ >
      -
      +
      Lesson {number} @@ -123,7 +123,7 @@ function TeaserSectionListItem({
      -

      +

      {description}

      diff --git a/src/components/learn-aggregator/learn-pages.tsx b/src/components/learn-aggregator/learn-pages.tsx index d6170ca719..f5043af0d1 100644 --- a/src/components/learn-aggregator/learn-pages.tsx +++ b/src/components/learn-aggregator/learn-pages.tsx @@ -17,134 +17,134 @@ const _items: Record< introduction: { description: "Get a high-level overview of GraphQL and how it enables flexible, versionless APIs powered by a strong type system.", - icon: new URL("./icons/computer.svg?raw", import.meta.url).href, + icon: new URL("./assets/computer.svg", import.meta.url).href, section: "getting-started", }, schema: { description: "Learn how GraphQL’s schema language defines the shape of your data using types.", - icon: new URL("./icons/hierarchy.svg", import.meta.url).href, + icon: new URL("./assets/hierarchy.svg", import.meta.url).href, section: "getting-started", }, queries: { description: "Understand how to structure GraphQL queries to request exactly the data you need — including fields, variables and fragments.", - icon: new URL("./icons/search.svg", import.meta.url).href, + icon: new URL("./assets/search.svg", import.meta.url).href, section: "getting-started", }, mutations: { description: "Explore how to modify data with mutations, including how to update and remove records through your schema.", - icon: new URL("./icons/construction.svg", import.meta.url).href, + icon: new URL("./assets/dna.svg", import.meta.url).href, section: "getting-started", }, subscriptions: { description: "Discover how GraphQL supports real-time data with subscriptions and how to use them effectively at scale.", - icon: new URL("./icons/sync-square.svg", import.meta.url).href, + icon: new URL("./assets/sync-square.svg", import.meta.url).href, section: "getting-started", }, validation: { description: "See how GraphQL ensures query correctness through validation rules and how common errors are detected early.", - icon: new URL("./icons/product-check.svg", import.meta.url).href, + icon: new URL("./assets/checkbox.svg", import.meta.url).href, section: "getting-started", }, execution: { description: "Learn how resolvers power GraphQL execution and how the server processes and returns data for each query.", - icon: new URL("./icons/board.svg", import.meta.url).href, + icon: new URL("./assets/cog-double.svg", import.meta.url).href, section: "getting-started", }, response: { description: "Explore how GraphQL structures its responses, including data, errors and extensions for custom metadata.", - icon: new URL("./icons/share.svg", import.meta.url).href, + icon: new URL("./assets/nav-left-circle.svg", import.meta.url).href, section: "getting-started", }, introspection: { description: "Use introspection to explore the schema itself — a powerful way to inspect types and fields dynamically.", - icon: new URL("./icons/zoom-page.svg", import.meta.url).href, + icon: new URL("./assets/zoom-page.svg", import.meta.url).href, section: "getting-started", }, // --- "best-practices": { description: "Practical guidance for common GraphQL concerns like networking, authorization, and pagination.", - icon: new URL("./icons/books.svg", import.meta.url).href, + icon: new URL("./assets/books.svg", import.meta.url).href, section: "best-practices", }, "thinking-in-graphs": { description: "Learn how to shift your mindset from RESTful endpoints to graph-based thinking, aligning your schema with business logic and legacy systems.", - icon: new URL("./icons/layer.svg", import.meta.url).href, + icon: new URL("./assets/layer.svg", import.meta.url).href, section: "best-practices", }, "serving-over-http": { description: "Explore how GraphQL operates over HTTP, including methods, headers, status codes and API endpoint design.", - icon: new URL("./icons/globe.svg", import.meta.url).href, + icon: new URL("./assets/globe.svg", import.meta.url).href, section: "best-practices", }, "file-uploads": { description: "Handle file uploads in GraphQL by wrapping them as mutations. Learn the recommended approach for integrating file handling into your API.", - icon: new URL("./icons/note.svg", import.meta.url).href, + icon: new URL("./assets/note.svg", import.meta.url).href, section: "best-practices", }, authorization: { description: "Understand how to secure your GraphQL APIs with type- and field-level authorization patterns.", - icon: new URL("./icons/key.svg", import.meta.url).href, + icon: new URL("./assets/key.svg", import.meta.url).href, section: "best-practices", }, pagination: { description: "Discover different pagination strategies in GraphQL, from simple slicing to fully connected edges and nodes.", - icon: new URL("./icons/menu.svg", import.meta.url).href, + icon: new URL("./assets/checkbox.svg", import.meta.url).href, section: "best-practices", }, "schema-design": { description: "Learn how to design clear, adaptable schemas — including versioning and thoughtful use of nullability.", - icon: new URL("./icons/cog-double.svg", import.meta.url).href, + icon: new URL("./assets/cog-double.svg", import.meta.url).href, section: "best-practices", }, "global-object-identification": { description: "Use globally unique IDs and the Node interface to enable caching, refetching, and efficient schema traversal.", - icon: new URL("./icons/dna.svg", import.meta.url).href, + icon: new URL("./assets/dna.svg", import.meta.url).href, section: "best-practices", }, caching: { description: "Explore caching techniques and ID strategies that make client-side performance and object reuse more effective.", - icon: new URL("./icons/sync-square.svg", import.meta.url).href, + icon: new URL("./assets/sync-square.svg", import.meta.url).href, section: "best-practices", }, performance: { description: "Get practical tips for improving GraphQL performance — from preventing N+1 problems to monitoring and compression.", - icon: new URL("./icons/startup.svg", import.meta.url).href, + icon: new URL("./assets/startup.svg", import.meta.url).href, section: "best-practices", }, security: { description: "Protect your GraphQL API with best practices for query limits, input validation, introspection control and more.", - icon: new URL("./icons/safe.svg", import.meta.url).href, + icon: new URL("./assets/safe.svg", import.meta.url).href, section: "best-practices", }, federation: { description: "Learn how GraphQL federation enables modular, scalable APIs by composing services into a unified schema.", - icon: new URL("./icons/globe.svg", import.meta.url).href, + icon: new URL("./assets/globe.svg", import.meta.url).href, section: "best-practices", }, "debug-errors": { description: "Learn about common 'graphql-http' errors and how to debug them.", - icon: new URL("./icons/solve.svg", import.meta.url).href, + icon: new URL("./assets/solve.svg", import.meta.url).href, section: "best-practices", }, } From 4b9bcb016c167f8d9752faba8b6bfcb87f2e4ed3 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Thu, 27 Nov 2025 15:21:09 +0100 Subject: [PATCH 31/58] Match icons, improve styles --- .../assets/{board.svg => circuit.svg} | 0 src/components/learn-aggregator/index.tsx | 32 +++++++++---------- .../learn-aggregator/learn-pages.tsx | 21 +++++------- src/components/toc-hero/index.tsx | 2 +- src/pages/learn/index.mdx | 4 +-- 5 files changed, 27 insertions(+), 32 deletions(-) rename src/components/learn-aggregator/assets/{board.svg => circuit.svg} (100%) diff --git a/src/components/learn-aggregator/assets/board.svg b/src/components/learn-aggregator/assets/circuit.svg similarity index 100% rename from src/components/learn-aggregator/assets/board.svg rename to src/components/learn-aggregator/assets/circuit.svg diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index d5bea077f0..85444c1c29 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -35,12 +35,12 @@ export function TeaserSection({ return (
      -
      +
      {eyebrow}

      {title}

      @@ -50,7 +50,7 @@ export function TeaserSection({ {cta}
      -
        +
          {items.map((item, index) => { return ( @@ -97,12 +97,12 @@ function TeaserSectionListItem({ href, }: TeaserSectionListItemProps) { return ( -
        • +
        • -
          {icon} -
          + -
          - + + Lesson {number} - + {title} - -
          + + -

          +

          {description}

          -
          + -
          +
        • ) diff --git a/src/components/learn-aggregator/learn-pages.tsx b/src/components/learn-aggregator/learn-pages.tsx index f5043af0d1..ec179edacb 100644 --- a/src/components/learn-aggregator/learn-pages.tsx +++ b/src/components/learn-aggregator/learn-pages.tsx @@ -69,16 +69,11 @@ const _items: Record< section: "getting-started", }, // --- - "best-practices": { - description: - "Practical guidance for common GraphQL concerns like networking, authorization, and pagination.", - icon: new URL("./assets/books.svg", import.meta.url).href, - section: "best-practices", - }, + "best-practices": null, "thinking-in-graphs": { description: "Learn how to shift your mindset from RESTful endpoints to graph-based thinking, aligning your schema with business logic and legacy systems.", - icon: new URL("./assets/layer.svg", import.meta.url).href, + icon: new URL("./assets/share.svg", import.meta.url).href, section: "best-practices", }, "serving-over-http": { @@ -102,25 +97,25 @@ const _items: Record< pagination: { description: "Discover different pagination strategies in GraphQL, from simple slicing to fully connected edges and nodes.", - icon: new URL("./assets/checkbox.svg", import.meta.url).href, + icon: new URL("./assets/layer.svg", import.meta.url).href, section: "best-practices", }, "schema-design": { description: "Learn how to design clear, adaptable schemas — including versioning and thoughtful use of nullability.", - icon: new URL("./assets/cog-double.svg", import.meta.url).href, + icon: new URL("./assets/solve.svg", import.meta.url).href, section: "best-practices", }, "global-object-identification": { description: "Use globally unique IDs and the Node interface to enable caching, refetching, and efficient schema traversal.", - icon: new URL("./assets/dna.svg", import.meta.url).href, + icon: new URL("./assets/product-check.svg", import.meta.url).href, section: "best-practices", }, caching: { description: "Explore caching techniques and ID strategies that make client-side performance and object reuse more effective.", - icon: new URL("./assets/sync-square.svg", import.meta.url).href, + icon: new URL("./assets/books.svg", import.meta.url).href, section: "best-practices", }, performance: { @@ -138,13 +133,13 @@ const _items: Record< federation: { description: "Learn how GraphQL federation enables modular, scalable APIs by composing services into a unified schema.", - icon: new URL("./assets/globe.svg", import.meta.url).href, + icon: new URL("./assets/circuit.svg", import.meta.url).href, section: "best-practices", }, "debug-errors": { description: "Learn about common 'graphql-http' errors and how to debug them.", - icon: new URL("./assets/solve.svg", import.meta.url).href, + icon: new URL("./assets/construction.svg", import.meta.url).href, section: "best-practices", }, } diff --git a/src/components/toc-hero/index.tsx b/src/components/toc-hero/index.tsx index b9f20bf63c..a35362fba7 100644 --- a/src/components/toc-hero/index.tsx +++ b/src/components/toc-hero/index.tsx @@ -12,7 +12,7 @@ export function TocHero({ heading, text, children, decoration }: TocHeroProps) { {decoration}

          {heading}

          -

          {text}

          +

          {text}

          {children}
      diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index e57cfda70d..5e13ef2c34 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -33,7 +33,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' description= "In this tutorial-style introduction to GraphQL, you'll learn the core concepts that power every GraphQL API. Follow a step-by-step path from basic queries to advanced features." cta={ - } @@ -48,7 +48,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' description= "Here you'll explore real-world strategies for designing and operating GraphQL APIs. These guides will help you build for scale and safety." cta={ - } From d71173c932c5fd6077ca1a8456caf0589918450f Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Thu, 27 Nov 2025 15:21:19 +0100 Subject: [PATCH 32/58] Remove the redundant CTA from Events page --- src/app/(main)/community/events/page.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/app/(main)/community/events/page.tsx b/src/app/(main)/community/events/page.tsx index 7f3bb6afff..f5e2c36f78 100644 --- a/src/app/(main)/community/events/page.tsx +++ b/src/app/(main)/community/events/page.tsx @@ -37,9 +37,6 @@ export default async function EventsPage() { text="Connect with the GraphQL community through events and meetups around the world." decoration={} > - Date: Thu, 27 Nov 2025 16:37:00 +0100 Subject: [PATCH 33/58] Add a TODO --- src/components/learn-aggregator/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 85444c1c29..3136bb768b 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -116,6 +116,7 @@ function TeaserSectionListItem({ + {/* TODO: Are we really sure these are Lessons? */} Lesson {number} From 4eb7646773cf3a8c5d9f7cd8e8026ef64b551ca9 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Thu, 27 Nov 2025 17:28:20 +0100 Subject: [PATCH 34/58] Tweak color in dark mode --- src/_design-system/eyebrow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_design-system/eyebrow.tsx b/src/_design-system/eyebrow.tsx index b75694c05d..8367fb1d26 100644 --- a/src/_design-system/eyebrow.tsx +++ b/src/_design-system/eyebrow.tsx @@ -18,7 +18,7 @@ export function Eyebrow({ return ( Date: Thu, 27 Nov 2025 17:28:35 +0100 Subject: [PATCH 35/58] Hide items in CSS --- src/components/learn-aggregator/index.tsx | 88 ++++++++++++++--------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 3136bb768b..1b3922080e 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -1,11 +1,13 @@ -import { ReactNode } from "react" +import { ReactNode, useState } from "react" +import { clsx } from "clsx" import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" -import { Eyebrow } from "@/_design-system/eyebrow" import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" +import { Eyebrow } from "@/_design-system/eyebrow" + import blurBean from "./learn-blur-bean.webp" -import clsx from "clsx" +import { Button } from "@/app/conf/_design-system/button" export interface TeaserSectionProps extends React.HTMLAttributes { @@ -32,6 +34,8 @@ export function TeaserSection({ className, ...rest }: TeaserSectionProps) { + const [showingMore, showMore] = useState(false) + return (
      -
        - {items.map((item, index) => { - return ( - - } - /> - ) - })} -
      +
      +
        + {items.map((item, index) => { + return ( + + } + /> + ) + })} +
      + +
      ) } // https://www.figma.com/design/aPUvZDSxJfYDJtPd7GF2sB/GraphQL.org--Working-File?node-id=6368-6983&t=JE1eYbp6gpQRUILY-4 // https://www.figma.com/design/aPUvZDSxJfYDJtPd7GF2sB/GraphQL.org--Working-File?node-id=5830-51637&t=JE1eYbp6gpQRUILY-4 -interface TeaserSectionListItemProps { +interface TeaserSectionListItemProps + extends React.HTMLAttributes { number: number title: string description: string @@ -95,16 +113,18 @@ function TeaserSectionListItem({ icon, section, href, + className, + ...rest }: TeaserSectionListItemProps) { return ( -
    • +
    • -

      +

      {description}

      - +
      @@ -141,7 +161,7 @@ export function LearnHeroStripes() {
      Date: Thu, 27 Nov 2025 17:40:41 +0100 Subject: [PATCH 36/58] Do not display Show less --- src/components/learn-aggregator/index.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index 1b3922080e..cd04962702 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -83,13 +83,16 @@ export function TeaserSection({ ) })} - + {!showingMore && ( + + )}
    • ) From 44deb18581ed53355afb56e93584b08b8eba6823 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 19:56:25 +0100 Subject: [PATCH 37/58] wip --- src/components/learn-aggregator/index.tsx | 4 +--- src/pages/learn/index.mdx | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/learn-aggregator/index.tsx b/src/components/learn-aggregator/index.tsx index cd04962702..e2f6417f2b 100644 --- a/src/components/learn-aggregator/index.tsx +++ b/src/components/learn-aggregator/index.tsx @@ -39,7 +39,7 @@ export function TeaserSection({ return (
      { number: number diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 5e13ef2c34..c2eb73cad9 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -3,6 +3,8 @@ import { Button } from '@/app/conf/_design-system/button'; import { TocHero, TocHeroContents } from '../../components/toc-hero'; import { TeaserSection, LearnHeroStripes } from '../../components/learn-aggregator' import { pagesBySection } from '../../components/learn-aggregator/learn-pages' +import { CommonQuestionsSection } from '../../components/learn-aggregator/common-questions' +import { TrainingCoursesSection } from '../../components/learn-aggregator/training-courses' import { NavbarFixed } from '../../components/navbar/navbar-fixed' @@ -54,3 +56,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' } items={pagesBySection["best-practices"]} /> + + + + From 4ac03042bb6013a8f6a1eeea3fd74b97c2f21e4e Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 19:58:27 +0100 Subject: [PATCH 38/58] wip --- .../learn-aggregator/common-questions.tsx | 16 +++ .../learn-aggregator/training-courses.tsx | 130 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/components/learn-aggregator/common-questions.tsx create mode 100644 src/components/learn-aggregator/training-courses.tsx diff --git a/src/components/learn-aggregator/common-questions.tsx b/src/components/learn-aggregator/common-questions.tsx new file mode 100644 index 0000000000..3a4a5d52e0 --- /dev/null +++ b/src/components/learn-aggregator/common-questions.tsx @@ -0,0 +1,16 @@ +import { clsx } from "clsx" + +import { Eyebrow } from "@/_design-system/eyebrow" + +export function CommonQuestionsSection( + props: React.HTMLAttributes, +) { + return ( +
      + FAQ +
      + ) +} diff --git a/src/components/learn-aggregator/training-courses.tsx b/src/components/learn-aggregator/training-courses.tsx new file mode 100644 index 0000000000..703a8b0d49 --- /dev/null +++ b/src/components/learn-aggregator/training-courses.tsx @@ -0,0 +1,130 @@ +import { clsx } from "clsx" + +import { Eyebrow } from "@/_design-system/eyebrow" +import { GraphQLLogo } from "@/app/conf/2025/components/graphql-conf-logo-link" +import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" +import ApolloLogo from "@/icons/apollo.svg?svgr" + +export function TrainingCoursesSection( + props: React.HTMLAttributes, +) { + return ( +
      +
      + Tutorials +

      Training Courses

      +

      + Get started or level up your GraphQL skills with these trusted + tutorials. +

      +
        +
      • + } + href="https://www.graphql-js.org/docs/" + /> +
      • +
      • + } + href="https://www.apollographql.com/tutorials/" + /> +
      • +
      • + } + href="https://the-guild.dev/graphql/yoga-server/tutorial/basic" + /> +
      • +
      • + } + href="https://hasura.io/learn/" + /> +
      • +
      +
      +
      + ) +} + +interface TrainingCoursesCardProps + extends React.LinkHTMLAttributes { + title: string + description: string + icon: React.ReactNode +} +function TrainingCoursesCard({ + title, + description, + icon, + href, + ...props +}: TrainingCoursesCardProps) { + return ( + +

      + {title} +

      +

      + {description} +

      + + {icon} + + + + +
      + ) +} + +function YogaLogo() { + return ( + + + + + + ) +} + +function HasuraLogo() { + return ( + + + + ) +} From 9197db4e389898e16ae4f3176e67ee9d265e8926 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 20:12:16 +0100 Subject: [PATCH 39/58] wip --- src/components/learn-aggregator/training-courses.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/learn-aggregator/training-courses.tsx b/src/components/learn-aggregator/training-courses.tsx index 703a8b0d49..ae6dfc7aa2 100644 --- a/src/components/learn-aggregator/training-courses.tsx +++ b/src/components/learn-aggregator/training-courses.tsx @@ -75,7 +75,7 @@ function TrainingCoursesCard({ return ( -

      +

      {title}

      -

      +

      {description}

      - + {icon} From aba51424a1ebf7065c7aca4cd6448c36e81a1312 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 20:16:09 +0100 Subject: [PATCH 40/58] wip --- src/components/learn-aggregator/training-courses.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/learn-aggregator/training-courses.tsx b/src/components/learn-aggregator/training-courses.tsx index ae6dfc7aa2..5e0a3394aa 100644 --- a/src/components/learn-aggregator/training-courses.tsx +++ b/src/components/learn-aggregator/training-courses.tsx @@ -20,7 +20,7 @@ export function TrainingCoursesSection( Get started or level up your GraphQL skills with these trusted tutorials.

      -
        +
        • -

          +

          {title}

          -

          +

          {description}

          - + {icon} - +
          From 1d4e140bd520d5b42cbdabccd548942b1646e35f Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 20:51:37 +0100 Subject: [PATCH 41/58] Add Common Questions --- .../learn-aggregator/common-questions.tsx | 44 ++++++++++++++++++- .../learn-aggregator/training-courses.tsx | 2 +- src/components/toc-hero/index.tsx | 18 +++++++- src/pages/learn/index.mdx | 1 + 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/components/learn-aggregator/common-questions.tsx b/src/components/learn-aggregator/common-questions.tsx index 3a4a5d52e0..7cafe1d814 100644 --- a/src/components/learn-aggregator/common-questions.tsx +++ b/src/components/learn-aggregator/common-questions.tsx @@ -1,6 +1,8 @@ import { clsx } from "clsx" import { Eyebrow } from "@/_design-system/eyebrow" +import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" +import { Anchor } from "@/app/conf/_design-system/anchor" export function CommonQuestionsSection( props: React.HTMLAttributes, @@ -8,9 +10,49 @@ export function CommonQuestionsSection( return (
          FAQ +

          Common questions

          +

          + Find answers to the most common questions about GraphQL — from getting + started to advanced use cases. This also covers frontend concerns and + info about the official specification. +

          +
            + + + + + + +
          ) } + +function CommonQuestionsItem({ title, href }: { title: string; href: string }) { + return ( +
        • + + {title} + + +
        • + ) +} diff --git a/src/components/learn-aggregator/training-courses.tsx b/src/components/learn-aggregator/training-courses.tsx index 5e0a3394aa..7c9e4d2ced 100644 --- a/src/components/learn-aggregator/training-courses.tsx +++ b/src/components/learn-aggregator/training-courses.tsx @@ -11,7 +11,7 @@ export function TrainingCoursesSection( return (
          Tutorials diff --git a/src/components/toc-hero/index.tsx b/src/components/toc-hero/index.tsx index a35362fba7..424fa6969a 100644 --- a/src/components/toc-hero/index.tsx +++ b/src/components/toc-hero/index.tsx @@ -1,3 +1,5 @@ +import { clsx } from "clsx" + export { TocHeroContents } from "./toc-hero-contents" export interface TocHeroProps { @@ -5,10 +7,22 @@ export interface TocHeroProps { text: React.ReactNode children: React.ReactNode decoration: React.ReactNode + className?: string } -export function TocHero({ heading, text, children, decoration }: TocHeroProps) { +export function TocHero({ + heading, + text, + children, + decoration, + className, +}: TocHeroProps) { return ( -
          +
          {decoration}

          {heading}

          diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index c2eb73cad9..0f35df9b87 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -9,6 +9,7 @@ import { NavbarFixed } from '../../components/navbar/navbar-fixed' From 6f8d177a1ab40da5bad4ebd9535efee7aea2fa0d Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 21:27:31 +0100 Subject: [PATCH 42/58] Add LookingForMore --- .../learn-aggregator/looking-for-more.tsx | 37 +++++++++++++++++++ src/pages/learn/index.mdx | 5 ++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/components/learn-aggregator/looking-for-more.tsx diff --git a/src/components/learn-aggregator/looking-for-more.tsx b/src/components/learn-aggregator/looking-for-more.tsx new file mode 100644 index 0000000000..768aaa62da --- /dev/null +++ b/src/components/learn-aggregator/looking-for-more.tsx @@ -0,0 +1,37 @@ +import { clsx } from "clsx" +import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" + +export function LookingForMore(props: React.HTMLAttributes) { + return ( +
          +
          +
          +

          Looking for more?

          +

          + Learning is just the beginning. Discover tools and other resources — + or connect with the GraphQL community around the world. +

          +
          + +
          +
          + ) +} diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index 0f35df9b87..e3462ff6a9 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -1,11 +1,12 @@ import { Button } from '@/app/conf/_design-system/button'; +import { NavbarFixed } from '../../components/navbar/navbar-fixed' import { TocHero, TocHeroContents } from '../../components/toc-hero'; import { TeaserSection, LearnHeroStripes } from '../../components/learn-aggregator' import { pagesBySection } from '../../components/learn-aggregator/learn-pages' import { CommonQuestionsSection } from '../../components/learn-aggregator/common-questions' import { TrainingCoursesSection } from '../../components/learn-aggregator/training-courses' -import { NavbarFixed } from '../../components/navbar/navbar-fixed' +import { LookingForMore } from "../../components/learn-aggregator/looking-for-more" + + From 7c6d103a5bf9099fc87d0f075516beb5b39e9b21 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Fri, 28 Nov 2025 21:34:06 +0100 Subject: [PATCH 43/58] Move the export down to work around the hMR hydration bug --- src/components/learn-aggregator/learn-pages.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/components/learn-aggregator/learn-pages.tsx b/src/components/learn-aggregator/learn-pages.tsx index ec179edacb..36fb291e90 100644 --- a/src/components/learn-aggregator/learn-pages.tsx +++ b/src/components/learn-aggregator/learn-pages.tsx @@ -144,13 +144,12 @@ const _items: Record< }, } -export const learnPages = _items as Record +const learnPages = _items as Record -export const pagesBySection: Record = - { - "getting-started": [], - "best-practices": [], - } +const pagesBySection: Record = { + "getting-started": [], + "best-practices": [], +} for (const path in learnPages) { const page = learnPages[path as LearnPagePath] @@ -171,3 +170,5 @@ for (const path in learnPages) { pagesBySection[page.section].push(page) } + +export { learnPages, pagesBySection } From b5883160c75b34d45a47c655f96c23ab427f198c Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 13:11:11 +0100 Subject: [PATCH 44/58] Rebuild --- scripts/get-github-info/github-stats.json | 706 +++++++++--------- scripts/get-github-info/last-success.isodate | 2 +- .../working-group-events.ndjson | 4 + 3 files changed, 358 insertions(+), 354 deletions(-) diff --git a/scripts/get-github-info/github-stats.json b/scripts/get-github-info/github-stats.json index 575c2e84fa..9f6b835af8 100644 --- a/scripts/get-github-info/github-stats.json +++ b/scripts/get-github-info/github-stats.json @@ -1,15 +1,15 @@ { "altair-graphql/altair": { "hasCommitsInLast3Months": false, - "stars": 5361, + "stars": 5365, "formattedStars": "5k", "license": "MIT License", "lastRelease": "2025-10-28T22:43:22Z", - "formattedLastRelease": "2 weeks ago" + "formattedLastRelease": "1 month ago" }, "apache/apisix": { "hasCommitsInLast3Months": false, - "stars": 15866, + "stars": 15907, "formattedStars": "16k", "license": "Apache License 2.0", "lastRelease": "2025-10-16T07:54:57Z", @@ -17,23 +17,23 @@ }, "apollographql/apollo-studio-community": { "hasCommitsInLast3Months": false, - "stars": 260, - "formattedStars": "260", + "stars": 261, + "formattedStars": "261", "license": "Unknown", "lastRelease": "", "formattedLastRelease": "" }, "ChilliCream/hotchocolate": { "hasCommitsInLast3Months": false, - "stars": 5621, + "stars": 5637, "formattedStars": "6k", "license": "MIT License", - "lastRelease": "2025-11-18T21:41:46Z", - "formattedLastRelease": "5 minutes ago" + "lastRelease": "2025-11-26T11:12:44Z", + "formattedLastRelease": "3 days ago" }, "dgraph-io/dgraph": { "hasCommitsInLast3Months": false, - "stars": 21350, + "stars": 21367, "formattedStars": "21k", "license": "Apache License 2.0", "lastRelease": "2025-10-07T20:50:36Z", @@ -41,7 +41,7 @@ }, "yahoo/elide": { "hasCommitsInLast3Months": false, - "stars": 1019, + "stars": 1020, "formattedStars": "1k", "license": "Other", "lastRelease": "2025-09-01T03:57:54Z", @@ -49,15 +49,15 @@ }, "graphapi-io/resources": { "hasCommitsInLast3Months": false, - "stars": 3, - "formattedStars": "3", + "stars": 4, + "formattedStars": "4", "license": "MIT License", "lastRelease": "", "formattedLastRelease": "" }, "hasura/graphql-engine": { "hasCommitsInLast3Months": false, - "stars": 31815, + "stars": 31827, "formattedStars": "32k", "license": "Apache License 2.0", "lastRelease": "2025-10-14T15:20:38Z", @@ -65,23 +65,23 @@ }, "graphql-hive/platform": { "hasCommitsInLast3Months": false, - "stars": 469, - "formattedStars": "469", + "stars": 471, + "formattedStars": "471", "license": "MIT License", - "lastRelease": "2025-11-18T10:07:16Z", - "formattedLastRelease": "11 hours ago" + "lastRelease": "2025-11-25T15:15:47Z", + "formattedLastRelease": "3 days ago" }, "Kong/insomnia": { "hasCommitsInLast3Months": false, - "stars": 37563, + "stars": 37611, "formattedStars": "38k", "license": "Apache License 2.0", - "lastRelease": "2025-11-14T09:22:34Z", - "formattedLastRelease": "4 days ago" + "lastRelease": "2025-11-21T17:29:45Z", + "formattedLastRelease": "1 week ago" }, "postmanlabs/postman-app-support": { "hasCommitsInLast3Months": false, - "stars": 5973, + "stars": 5979, "formattedStars": "6k", "license": "Unknown", "lastRelease": "", @@ -89,31 +89,31 @@ }, "stepzen-dev/examples": { "hasCommitsInLast3Months": false, - "stars": 46, - "formattedStars": "46", + "stars": 47, + "formattedStars": "47", "license": "MIT License", "lastRelease": "", "formattedLastRelease": "" }, "TykTechnologies/tyk": { "hasCommitsInLast3Months": false, - "stars": 10484, - "formattedStars": "10k", + "stars": 10515, + "formattedStars": "11k", "license": "Other", - "lastRelease": "2025-10-24T18:32:20Z", - "formattedLastRelease": "3 weeks ago" + "lastRelease": "2025-11-28T16:32:34Z", + "formattedLastRelease": "19 hours ago" }, "twinlogix/typetta": { "hasCommitsInLast3Months": false, - "stars": 114, - "formattedStars": "114", + "stars": 115, + "formattedStars": "115", "license": "Apache License 2.0", "lastRelease": "2023-10-16T07:50:50Z", "formattedLastRelease": "2 years ago" }, "webiny/webiny-js": { "hasCommitsInLast3Months": false, - "stars": 7890, + "stars": 7894, "formattedStars": "8k", "license": "Other", "lastRelease": "2025-09-16T08:29:00Z", @@ -121,28 +121,60 @@ }, "ballerina-platform/module-ballerina-graphql": { "hasCommitsInLast3Months": false, - "stars": 139, - "formattedStars": "139", + "stars": 138, + "formattedStars": "138", "license": "Apache License 2.0", "lastRelease": "2025-11-06T10:54:08Z", - "formattedLastRelease": "1 week ago" + "formattedLastRelease": "3 weeks ago" + }, + "oliyh/re-graph": { + "hasCommitsInLast3Months": false, + "stars": 464, + "formattedStars": "464", + "license": "Unknown", + "lastRelease": "2022-07-20T09:24:02Z", + "formattedLastRelease": "3 years ago" }, "microsoft/cppgraphqlgen": { "hasCommitsInLast3Months": false, - "stars": 344, - "formattedStars": "344", + "stars": 343, + "formattedStars": "343", "license": "MIT License", "lastRelease": "2024-12-10T17:25:31Z", "formattedLastRelease": "11 months ago" }, "graphql/libgraphqlparser": { "hasCommitsInLast3Months": false, - "stars": 1101, + "stars": 1102, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2017-10-16T21:47:42Z", "formattedLastRelease": "8 years ago" }, + "alumbra/alumbra": { + "hasCommitsInLast3Months": false, + "stars": 148, + "formattedStars": "148", + "license": "MIT License", + "lastRelease": "2017-06-12T12:14:25Z", + "formattedLastRelease": "8 years ago" + }, + "tendant/graphql-clj": { + "hasCommitsInLast3Months": false, + "stars": 285, + "formattedStars": "285", + "license": "Eclipse Public License 1.0", + "lastRelease": "", + "formattedLastRelease": "" + }, + "walmartlabs/lacinia": { + "hasCommitsInLast3Months": false, + "stars": 1843, + "formattedStars": "2k", + "license": "Other", + "lastRelease": "", + "formattedLastRelease": "" + }, "graphql-dotnet/graphql-client": { "hasCommitsInLast3Months": false, "stars": 644, @@ -165,7 +197,7 @@ "formattedStars": "8", "license": "MIT License", "lastRelease": "2025-11-14T07:39:17Z", - "formattedLastRelease": "4 days ago" + "formattedLastRelease": "2 weeks ago" }, "sahb1239/SAHB.GraphQLClient": { "hasCommitsInLast3Months": false, @@ -177,27 +209,27 @@ }, "byme8/ZeroQL": { "hasCommitsInLast3Months": false, - "stars": 312, - "formattedStars": "312", + "stars": 313, + "formattedStars": "313", "license": "MIT License", "lastRelease": "2025-10-14T11:58:44Z", "formattedLastRelease": "1 month ago" }, "EntityGraphQL/EntityGraphQL": { "hasCommitsInLast3Months": false, - "stars": 448, - "formattedStars": "448", + "stars": 449, + "formattedStars": "449", "license": "MIT License", "lastRelease": "2025-09-16T00:35:14Z", "formattedLastRelease": "2 months ago" }, "graphql-dotnet/graphql-dotnet": { "hasCommitsInLast3Months": false, - "stars": 5977, + "stars": 5975, "formattedStars": "6k", "license": "MIT License", "lastRelease": "2025-11-17T17:57:35Z", - "formattedLastRelease": "1 day ago" + "formattedLastRelease": "1 week ago" }, "chkimes/graphql-net": { "hasCommitsInLast3Months": false, @@ -215,38 +247,6 @@ "lastRelease": "", "formattedLastRelease": "" }, - "oliyh/re-graph": { - "hasCommitsInLast3Months": false, - "stars": 466, - "formattedStars": "466", - "license": "Unknown", - "lastRelease": "2022-07-20T09:24:02Z", - "formattedLastRelease": "3 years ago" - }, - "alumbra/alumbra": { - "hasCommitsInLast3Months": false, - "stars": 148, - "formattedStars": "148", - "license": "MIT License", - "lastRelease": "2017-06-12T12:14:25Z", - "formattedLastRelease": "8 years ago" - }, - "tendant/graphql-clj": { - "hasCommitsInLast3Months": false, - "stars": 285, - "formattedStars": "285", - "license": "Eclipse Public License 1.0", - "lastRelease": "", - "formattedLastRelease": "" - }, - "walmartlabs/lacinia": { - "hasCommitsInLast3Months": false, - "stars": 1844, - "formattedStars": "2k", - "license": "Other", - "lastRelease": "", - "formattedLastRelease": "" - }, "burner/graphqld": { "hasCommitsInLast3Months": false, "stars": 35, @@ -273,10 +273,10 @@ }, "absinthe-graphql/absinthe": { "hasCommitsInLast3Months": false, - "stars": 4369, + "stars": 4374, "formattedStars": "4k", "license": "Other", - "lastRelease": "2025-11-06T13:26:50Z", + "lastRelease": "2025-11-21T15:08:24Z", "formattedLastRelease": "1 week ago" }, "graphql-elixir/graphql": { @@ -313,15 +313,15 @@ }, "zino-app/graphql-flutter": { "hasCommitsInLast3Months": false, - "stars": 3269, + "stars": 3270, "formattedStars": "3k", "license": "MIT License", "lastRelease": "2025-10-21T16:42:55Z", - "formattedLastRelease": "4 weeks ago" + "formattedLastRelease": "1 month ago" }, "Khan/genqlient": { "hasCommitsInLast3Months": false, - "stars": 1265, + "stars": 1266, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-05-18T19:09:08Z", @@ -329,15 +329,15 @@ }, "hasura/go-graphql-client": { "hasCommitsInLast3Months": false, - "stars": 455, - "formattedStars": "455", + "stars": 459, + "formattedStars": "459", "license": "MIT License", "lastRelease": "2025-11-05T06:45:53Z", - "formattedLastRelease": "1 week ago" + "formattedLastRelease": "3 weeks ago" }, "shurcooL/graphql": { "hasCommitsInLast3Months": false, - "stars": 727, + "stars": 728, "formattedStars": "1k", "license": "MIT License", "lastRelease": "", @@ -345,7 +345,7 @@ }, "machinebox/graphql": { "hasCommitsInLast3Months": false, - "stars": 960, + "stars": 961, "formattedStars": "1k", "license": "Apache License 2.0", "lastRelease": "2018-05-31T14:28:32Z", @@ -353,11 +353,11 @@ }, "99designs/gqlgen": { "hasCommitsInLast3Months": false, - "stars": 10583, + "stars": 10593, "formattedStars": "11k", "license": "MIT License", - "lastRelease": "2025-11-11T02:05:44Z", - "formattedLastRelease": "1 week ago" + "lastRelease": "2025-11-24T16:56:20Z", + "formattedLastRelease": "4 days ago" }, "andrewwphillips/eggql": { "hasCommitsInLast3Months": false, @@ -377,7 +377,7 @@ }, "graph-gophers/graphql-go": { "hasCommitsInLast3Months": false, - "stars": 4739, + "stars": 4741, "formattedStars": "5k", "license": "BSD 2-Clause \"Simplified\" License", "lastRelease": "2025-09-09T11:37:07Z", @@ -385,7 +385,7 @@ }, "graphql-go/graphql": { "hasCommitsInLast3Months": false, - "stars": 10129, + "stars": 10132, "formattedStars": "10k", "license": "MIT License", "lastRelease": "2023-04-10T18:20:23Z", @@ -412,16 +412,16 @@ "stars": 790, "formattedStars": "1k", "license": "MIT License", - "lastRelease": "2025-11-17T08:37:55Z", - "formattedLastRelease": "1 day ago" + "lastRelease": "2025-11-21T21:18:20Z", + "formattedLastRelease": "1 week ago" }, "dosco/graphjin": { "hasCommitsInLast3Months": false, - "stars": 3002, + "stars": 3011, "formattedStars": "3k", "license": "Apache License 2.0", "lastRelease": "2025-11-05T07:51:12Z", - "formattedLastRelease": "1 week ago" + "formattedLastRelease": "3 weeks ago" }, "grails/gorm-graphql": { "hasCommitsInLast3Months": false, @@ -463,117 +463,21 @@ "lastRelease": "2021-01-11T11:19:38Z", "formattedLastRelease": "4 years ago" }, - "apollographql/apollo-kotlin": { - "hasCommitsInLast3Months": false, - "stars": 3927, - "formattedStars": "4k", - "license": "MIT License", - "lastRelease": "2025-11-13T17:33:51Z", - "formattedLastRelease": "5 days ago" - }, - "ExpediaGroup/graphql-kotlin": { - "hasCommitsInLast3Months": false, - "stars": 1795, - "formattedStars": "2k", - "license": "Apache License 2.0", - "lastRelease": "2025-06-16T17:02:18Z", - "formattedLastRelease": "5 months ago" - }, - "americanexpress/nodes": { - "hasCommitsInLast3Months": false, - "stars": 307, - "formattedStars": "307", - "license": "Apache License 2.0", - "lastRelease": "2019-07-13T22:47:01Z", - "formattedLastRelease": "6 years ago" - }, - "graphql-calculator/graphql-calculator": { - "hasCommitsInLast3Months": false, - "stars": 112, - "formattedStars": "112", - "license": "Apache License 2.0", - "lastRelease": "2021-09-03T01:56:25Z", - "formattedLastRelease": "4 years ago" - }, - "graphql-java-kickstart/graphql-spring-boot": { - "hasCommitsInLast3Months": false, - "stars": 1513, - "formattedStars": "2k", - "license": "MIT License", - "lastRelease": "2023-12-07T11:07:47Z", - "formattedLastRelease": "1 year ago" - }, - "graphql-java/graphql-java": { - "hasCommitsInLast3Months": false, - "stars": 6226, - "formattedStars": "6k", - "license": "MIT License", - "lastRelease": "2025-11-10T01:21:35Z", - "formattedLastRelease": "1 week ago" - }, - "babyfish-ct/jimmer": { - "hasCommitsInLast3Months": false, - "stars": 1552, - "formattedStars": "2k", - "license": "Apache License 2.0", - "lastRelease": "2025-11-17T08:58:28Z", - "formattedLastRelease": "1 day ago" - }, - "aPureBase/KGraphQL": { - "hasCommitsInLast3Months": false, - "stars": 308, - "formattedStars": "308", - "license": "MIT License", - "lastRelease": "2023-01-27T10:09:55Z", - "formattedLastRelease": "2 years ago" - }, - "eclipse/microprofile-graphql": { - "hasCommitsInLast3Months": false, - "stars": 101, - "formattedStars": "101", - "license": "Apache License 2.0", - "lastRelease": "2022-03-21T18:26:51Z", - "formattedLastRelease": "3 years ago" - }, - "netflix/dgs-framework": { - "hasCommitsInLast3Months": false, - "stars": 3275, - "formattedStars": "3k", - "license": "Apache License 2.0", - "lastRelease": "2025-11-08T16:22:51Z", - "formattedLastRelease": "1 week ago" - }, - "spring-projects/spring-graphql": { - "hasCommitsInLast3Months": false, - "stars": 1578, - "formattedStars": "2k", - "license": "Apache License 2.0", - "lastRelease": "2025-11-18T10:05:26Z", - "formattedLastRelease": "11 hours ago" - }, - "graphql-java-generator/graphql-gradle-plugin-project": { - "hasCommitsInLast3Months": false, - "stars": 57, - "formattedStars": "57", - "license": "MIT License", - "lastRelease": "", - "formattedLastRelease": "" - }, "apollographql/apollo-client": { "hasCommitsInLast3Months": false, - "stars": 19672, + "stars": 19673, "formattedStars": "20k", "license": "MIT License", - "lastRelease": "2025-11-17T21:21:55Z", - "formattedLastRelease": "1 day ago" + "lastRelease": "2025-11-19T01:20:25Z", + "formattedLastRelease": "1 week ago" }, "aws-amplify/amplify-js": { "hasCommitsInLast3Months": false, - "stars": 9565, + "stars": 9567, "formattedStars": "10k", "license": "Apache License 2.0", "lastRelease": "2025-11-06T13:36:19Z", - "formattedLastRelease": "1 week ago" + "formattedLastRelease": "3 weeks ago" }, "Houfeng/gq-loader": { "hasCommitsInLast3Months": false, @@ -585,11 +489,11 @@ }, "gqty-dev/gqty": { "hasCommitsInLast3Months": false, - "stars": 1031, + "stars": 1030, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-10-26T19:29:38Z", - "formattedLastRelease": "3 weeks ago" + "formattedLastRelease": "1 month ago" }, "grafoojs/grafoo": { "hasCommitsInLast3Months": false, @@ -609,7 +513,7 @@ }, "nearform/graphql-hooks": { "hasCommitsInLast3Months": false, - "stars": 1888, + "stars": 1889, "formattedStars": "2k", "license": "Other", "lastRelease": "2025-01-08T18:45:52Z", @@ -625,11 +529,11 @@ }, "jasonkuhrt/graphql-request": { "hasCommitsInLast3Months": false, - "stars": 6075, + "stars": 6081, "formattedStars": "6k", "license": "MIT License", - "lastRelease": "2020-05-29T13:00:56Z", - "formattedLastRelease": "5 years ago" + "lastRelease": "2025-11-25T16:55:56Z", + "formattedLastRelease": "3 days ago" }, "enisdenjo/graphql-sse": { "hasCommitsInLast3Months": false, @@ -637,7 +541,7 @@ "formattedStars": "435", "license": "MIT License", "lastRelease": "2025-10-22T16:19:40Z", - "formattedLastRelease": "3 weeks ago" + "formattedLastRelease": "1 month ago" }, "babyfish-ct/graphql-ts-client": { "hasCommitsInLast3Months": false, @@ -649,7 +553,7 @@ }, "enisdenjo/graphql-ws": { "hasCommitsInLast3Months": false, - "stars": 1842, + "stars": 1843, "formattedStars": "2k", "license": "MIT License", "lastRelease": "2025-07-14T12:15:37Z", @@ -681,7 +585,7 @@ }, "facebook/relay": { "hasCommitsInLast3Months": false, - "stars": 18887, + "stars": 18893, "formattedStars": "19k", "license": "MIT License", "lastRelease": "2025-08-06T23:45:00Z", @@ -689,56 +593,56 @@ }, "FormidableLabs/urql": { "hasCommitsInLast3Months": false, - "stars": 8893, + "stars": 8900, "formattedStars": "9k", "license": "MIT License", "lastRelease": "2025-08-29T08:06:41Z", - "formattedLastRelease": "2 months ago" + "formattedLastRelease": "3 months ago" }, "apollographql/apollo-server": { "hasCommitsInLast3Months": false, - "stars": 13924, + "stars": 13926, "formattedStars": "14k", "license": "MIT License", - "lastRelease": "2025-10-28T15:47:16Z", - "formattedLastRelease": "3 weeks ago" + "lastRelease": "2025-11-21T23:19:03Z", + "formattedLastRelease": "1 week ago" }, "graphql/graphql-js": { "hasCommitsInLast3Months": false, - "stars": 20270, + "stars": 20279, "formattedStars": "20k", "license": "MIT License", "lastRelease": "2025-11-01T14:18:53Z", - "formattedLastRelease": "2 weeks ago" + "formattedLastRelease": "3 weeks ago" }, "dotansimha/graphql-yoga": { "hasCommitsInLast3Months": false, - "stars": 8452, + "stars": 8455, "formattedStars": "8k", "license": "MIT License", - "lastRelease": "2025-11-07T02:09:51Z", - "formattedLastRelease": "1 week ago" + "lastRelease": "2025-11-28T11:05:21Z", + "formattedLastRelease": "1 day ago" }, "mercurius-js/mercurius": { "hasCommitsInLast3Months": false, - "stars": 2456, + "stars": 2462, "formattedStars": "2k", "license": "MIT License", "lastRelease": "2025-11-13T14:12:18Z", - "formattedLastRelease": "5 days ago" + "formattedLastRelease": "2 weeks ago" }, "getcronit/pylon": { "hasCommitsInLast3Months": false, - "stars": 343, - "formattedStars": "343", + "stars": 345, + "formattedStars": "345", "license": "Apache License 2.0", "lastRelease": "2025-10-01T08:35:15Z", "formattedLastRelease": "1 month ago" }, "networkimprov/brangr": { "hasCommitsInLast3Months": false, - "stars": 5, - "formattedStars": "5", + "stars": 6, + "formattedStars": "6", "license": "Mozilla Public License 2.0", "lastRelease": "2023-06-02T09:20:18Z", "formattedLastRelease": "2 years ago" @@ -749,15 +653,15 @@ "formattedStars": "3k", "license": "ISC License", "lastRelease": "2025-11-10T01:29:18Z", - "formattedLastRelease": "1 week ago" + "formattedLastRelease": "2 weeks ago" }, "graphql/graphiql": { "hasCommitsInLast3Months": false, - "stars": 16706, + "stars": 16715, "formattedStars": "17k", "license": "MIT License", "lastRelease": "2025-11-01T22:30:04Z", - "formattedLastRelease": "2 weeks ago" + "formattedLastRelease": "3 weeks ago" }, "Urigo/graphql-cli": { "hasCommitsInLast3Months": false, @@ -769,35 +673,35 @@ }, "dotansimha/graphql-code-generator": { "hasCommitsInLast3Months": false, - "stars": 11175, + "stars": 11179, "formattedStars": "11k", "license": "MIT License", - "lastRelease": "2025-11-13T15:19:33Z", - "formattedLastRelease": "5 days ago" + "lastRelease": "2025-11-29T04:07:19Z", + "formattedLastRelease": "7 hours ago" }, "kamilkisiela/graphql-config": { "hasCommitsInLast3Months": false, - "stars": 1194, + "stars": 1195, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-04-28T15:15:29Z", - "formattedLastRelease": "6 months ago" + "formattedLastRelease": "7 months ago" }, "dimaMachina/graphql-eslint/": { "hasCommitsInLast3Months": false, - "stars": 830, + "stars": 831, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-03-26T14:11:23Z", - "formattedLastRelease": "7 months ago" + "formattedLastRelease": "8 months ago" }, "kamilkisiela/graphql-inspector": { "hasCommitsInLast3Months": false, - "stars": 1727, + "stars": 1725, "formattedStars": "2k", "license": "MIT License", "lastRelease": "2025-11-15T02:42:13Z", - "formattedLastRelease": "3 days ago" + "formattedLastRelease": "2 weeks ago" }, "graphql/graphql-language-service": { "hasCommitsInLast3Months": false, @@ -809,18 +713,18 @@ }, "n1ru4l/graphql-live-query": { "hasCommitsInLast3Months": false, - "stars": 439, - "formattedStars": "439", + "stars": 440, + "formattedStars": "440", "license": "MIT License", "lastRelease": "2022-07-29T09:27:53Z", "formattedLastRelease": "3 years ago" }, "Urigo/graphql-mesh": { "hasCommitsInLast3Months": false, - "stars": 3459, + "stars": 3463, "formattedStars": "3k", "license": "MIT License", - "lastRelease": "2025-11-07T23:26:14Z", + "lastRelease": "2025-11-19T12:12:00Z", "formattedLastRelease": "1 week ago" }, "maticzav/graphql-middleware": { @@ -833,15 +737,15 @@ }, "Urigo/graphql-modules": { "hasCommitsInLast3Months": false, - "stars": 1328, + "stars": 1326, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-02-19T10:43:37Z", - "formattedLastRelease": "8 months ago" + "formattedLastRelease": "9 months ago" }, "Urigo/graphql-scalars": { "hasCommitsInLast3Months": false, - "stars": 1925, + "stars": 1927, "formattedStars": "2k", "license": "MIT License", "lastRelease": "2025-10-14T23:00:24Z", @@ -849,19 +753,19 @@ }, "maticzav/graphql-shield": { "hasCommitsInLast3Months": false, - "stars": 3573, + "stars": 3574, "formattedStars": "4k", "license": "MIT License", "lastRelease": "2022-11-22T19:08:37Z", - "formattedLastRelease": "2 years ago" + "formattedLastRelease": "3 years ago" }, "ardatan/graphql-tools": { "hasCommitsInLast3Months": false, - "stars": 5420, + "stars": 5418, "formattedStars": "5k", "license": "MIT License", - "lastRelease": "2025-11-12T10:07:43Z", - "formattedLastRelease": "6 days ago" + "lastRelease": "2025-11-28T10:05:14Z", + "formattedLastRelease": "1 day ago" }, "anvilco/graphql-introspection-tools": { "hasCommitsInLast3Months": false, @@ -873,7 +777,7 @@ }, "graphile/postgraphile": { "hasCommitsInLast3Months": false, - "stars": 12852, + "stars": 12858, "formattedStars": "13k", "license": "Other", "lastRelease": "2023-10-05T16:27:00Z", @@ -889,7 +793,7 @@ }, "anvilco/spectaql": { "hasCommitsInLast3Months": false, - "stars": 1203, + "stars": 1205, "formattedStars": "1k", "license": "MIT License", "lastRelease": "", @@ -929,7 +833,7 @@ }, "api-platform/api-platform": { "hasCommitsInLast3Months": false, - "stars": 9045, + "stars": 9054, "formattedStars": "9k", "license": "MIT License", "lastRelease": "2025-03-11T16:15:41Z", @@ -940,8 +844,8 @@ "stars": 376, "formattedStars": "376", "license": "GNU General Public License v2.0", - "lastRelease": "2025-10-17T15:10:13Z", - "formattedLastRelease": "1 month ago" + "lastRelease": "2025-11-26T08:29:30Z", + "formattedLastRelease": "3 days ago" }, "infinityloop-dev/graphpinator": { "hasCommitsInLast3Months": false, @@ -949,7 +853,7 @@ "formattedStars": "45", "license": "MIT License", "lastRelease": "2025-06-26T12:08:01Z", - "formattedLastRelease": "4 months ago" + "formattedLastRelease": "5 months ago" }, "jerowork/graphql-attribute-schema": { "hasCommitsInLast3Months": false, @@ -961,11 +865,11 @@ }, "webonyx/graphql-php": { "hasCommitsInLast3Months": false, - "stars": 4700, + "stars": 4702, "formattedStars": "5k", "license": "MIT License", - "lastRelease": "2025-10-25T09:34:10Z", - "formattedLastRelease": "3 weeks ago" + "lastRelease": "2025-11-20T11:51:16Z", + "formattedLastRelease": "1 week ago" }, "ivome/graphql-relay-php": { "hasCommitsInLast3Months": false, @@ -977,15 +881,15 @@ }, "overblog/GraphQLBundle": { "hasCommitsInLast3Months": false, - "stars": 791, + "stars": 792, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-10-31T08:00:22Z", - "formattedLastRelease": "2 weeks ago" + "formattedLastRelease": "4 weeks ago" }, "thecodingmachine/graphqlite": { "hasCommitsInLast3Months": false, - "stars": 564, + "stars": 565, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-09-04T16:39:26Z", @@ -993,7 +897,7 @@ }, "nuwave/lighthouse": { "hasCommitsInLast3Months": false, - "stars": 3462, + "stars": 3465, "formattedStars": "3k", "license": "MIT License", "lastRelease": "2025-09-11T08:07:50Z", @@ -1017,7 +921,7 @@ }, "leocavalcante/siler": { "hasCommitsInLast3Months": false, - "stars": 1114, + "stars": 1113, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2021-01-27T19:41:57Z", @@ -1028,20 +932,20 @@ "stars": 3759, "formattedStars": "4k", "license": "GNU General Public License v3.0", - "lastRelease": "2025-10-30T16:56:08Z", - "formattedLastRelease": "2 weeks ago" + "lastRelease": "2025-11-24T22:39:55Z", + "formattedLastRelease": "4 days ago" }, "mirumee/ariadne-codegen": { "hasCommitsInLast3Months": false, - "stars": 361, - "formattedStars": "361", + "stars": 368, + "formattedStars": "368", "license": "BSD 3-Clause \"New\" or \"Revised\" License", "lastRelease": "2025-10-13T06:38:02Z", "formattedLastRelease": "1 month ago" }, "graphql-python/gql": { "hasCommitsInLast3Months": false, - "stars": 1649, + "stars": 1653, "formattedStars": "2k", "license": "MIT License", "lastRelease": "2025-09-05T14:22:54Z", @@ -1057,8 +961,8 @@ }, "prisma-labs/python-graphql-client": { "hasCommitsInLast3Months": false, - "stars": 157, - "formattedStars": "157", + "stars": 156, + "formattedStars": "156", "license": "MIT License", "lastRelease": "", "formattedLastRelease": "" @@ -1089,7 +993,7 @@ }, "mirumee/ariadne": { "hasCommitsInLast3Months": false, - "stars": 2307, + "stars": 2309, "formattedStars": "2k", "license": "BSD 3-Clause \"New\" or \"Revised\" License", "lastRelease": "2025-04-18T08:27:47Z", @@ -1113,7 +1017,7 @@ }, "graphql-python/graphene": { "hasCommitsInLast3Months": false, - "stars": 8238, + "stars": 8239, "formattedStars": "8k", "license": "MIT License", "lastRelease": "2024-11-09T20:43:58Z", @@ -1121,11 +1025,11 @@ }, "strawberry-graphql/strawberry": { "hasCommitsInLast3Months": false, - "stars": 4467, - "formattedStars": "4k", + "stars": 4569, + "formattedStars": "5k", "license": "MIT License", - "lastRelease": "2025-11-18T18:05:57Z", - "formattedLastRelease": "3 hours ago" + "lastRelease": "2025-11-22T13:00:06Z", + "formattedLastRelease": "6 days ago" }, "tartiflette/tartiflette": { "hasCommitsInLast3Months": false, @@ -1135,6 +1039,102 @@ "lastRelease": "2021-11-15T11:05:03Z", "formattedLastRelease": "4 years ago" }, + "apollographql/apollo-kotlin": { + "hasCommitsInLast3Months": false, + "stars": 3929, + "formattedStars": "4k", + "license": "MIT License", + "lastRelease": "2025-11-13T17:33:51Z", + "formattedLastRelease": "2 weeks ago" + }, + "ExpediaGroup/graphql-kotlin": { + "hasCommitsInLast3Months": false, + "stars": 1795, + "formattedStars": "2k", + "license": "Apache License 2.0", + "lastRelease": "2025-06-16T17:02:18Z", + "formattedLastRelease": "5 months ago" + }, + "americanexpress/nodes": { + "hasCommitsInLast3Months": false, + "stars": 307, + "formattedStars": "307", + "license": "Apache License 2.0", + "lastRelease": "2019-07-13T22:47:01Z", + "formattedLastRelease": "6 years ago" + }, + "graphql-calculator/graphql-calculator": { + "hasCommitsInLast3Months": false, + "stars": 112, + "formattedStars": "112", + "license": "Apache License 2.0", + "lastRelease": "2021-09-03T01:56:25Z", + "formattedLastRelease": "4 years ago" + }, + "graphql-java-kickstart/graphql-spring-boot": { + "hasCommitsInLast3Months": false, + "stars": 1513, + "formattedStars": "2k", + "license": "MIT License", + "lastRelease": "2023-12-07T11:07:47Z", + "formattedLastRelease": "1 year ago" + }, + "graphql-java/graphql-java": { + "hasCommitsInLast3Months": false, + "stars": 6226, + "formattedStars": "6k", + "license": "MIT License", + "lastRelease": "2025-11-10T01:21:35Z", + "formattedLastRelease": "2 weeks ago" + }, + "babyfish-ct/jimmer": { + "hasCommitsInLast3Months": false, + "stars": 1565, + "formattedStars": "2k", + "license": "Apache License 2.0", + "lastRelease": "2025-11-26T13:05:27Z", + "formattedLastRelease": "2 days ago" + }, + "aPureBase/KGraphQL": { + "hasCommitsInLast3Months": false, + "stars": 308, + "formattedStars": "308", + "license": "MIT License", + "lastRelease": "2023-01-27T10:09:55Z", + "formattedLastRelease": "2 years ago" + }, + "eclipse/microprofile-graphql": { + "hasCommitsInLast3Months": false, + "stars": 101, + "formattedStars": "101", + "license": "Apache License 2.0", + "lastRelease": "2022-03-21T18:26:51Z", + "formattedLastRelease": "3 years ago" + }, + "netflix/dgs-framework": { + "hasCommitsInLast3Months": false, + "stars": 3280, + "formattedStars": "3k", + "license": "Apache License 2.0", + "lastRelease": "2025-11-24T21:04:55Z", + "formattedLastRelease": "4 days ago" + }, + "spring-projects/spring-graphql": { + "hasCommitsInLast3Months": false, + "stars": 1578, + "formattedStars": "2k", + "license": "Apache License 2.0", + "lastRelease": "2025-11-18T10:05:26Z", + "formattedLastRelease": "1 week ago" + }, + "graphql-java-generator/graphql-gradle-plugin-project": { + "hasCommitsInLast3Months": false, + "stars": 57, + "formattedStars": "57", + "license": "MIT License", + "lastRelease": "", + "formattedLastRelease": "" + }, "ropensci/ghql": { "hasCommitsInLast3Months": false, "stars": 149, @@ -1149,7 +1149,7 @@ "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-09-24T22:20:23Z", - "formattedLastRelease": "1 month ago" + "formattedLastRelease": "2 months ago" }, "rmosolgo/graphql-ruby": { "hasCommitsInLast3Months": false, @@ -1165,15 +1165,15 @@ "formattedStars": "187", "license": "MIT License", "lastRelease": "2025-08-25T17:53:38Z", - "formattedLastRelease": "2 months ago" + "formattedLastRelease": "3 months ago" }, "obmarg/cynic": { "hasCommitsInLast3Months": false, - "stars": 440, - "formattedStars": "440", + "stars": 442, + "formattedStars": "442", "license": "Mozilla Public License 2.0", "lastRelease": "2025-08-19T19:37:22Z", - "formattedLastRelease": "2 months ago" + "formattedLastRelease": "3 months ago" }, "arthurkhlghatyan/gql-client-rs": { "hasCommitsInLast3Months": false, @@ -1183,17 +1183,9 @@ "lastRelease": "2025-06-07T14:31:10Z", "formattedLastRelease": "5 months ago" }, - "ghostdogpr/caliban": { - "hasCommitsInLast3Months": false, - "stars": 975, - "formattedStars": "1k", - "license": "Apache License 2.0", - "lastRelease": "2025-07-14T00:24:20Z", - "formattedLastRelease": "4 months ago" - }, "async-graphql/async-graphql": { "hasCommitsInLast3Months": false, - "stars": 3588, + "stars": 3594, "formattedStars": "4k", "license": "Apache License 2.0", "lastRelease": "", @@ -1207,13 +1199,13 @@ "lastRelease": "2025-09-08T23:23:40Z", "formattedLastRelease": "2 months ago" }, - "apollographql/router": { + "ghostdogpr/caliban": { "hasCommitsInLast3Months": false, - "stars": 938, + "stars": 976, "formattedStars": "1k", - "license": "Other", - "lastRelease": "2025-11-11T14:49:10Z", - "formattedLastRelease": "1 week ago" + "license": "Apache License 2.0", + "lastRelease": "2025-07-14T00:24:20Z", + "formattedLastRelease": "4 months ago" }, "sangria-graphql/sangria": { "hasCommitsInLast3Months": false, @@ -1221,71 +1213,15 @@ "formattedStars": "2k", "license": "Apache License 2.0", "lastRelease": "2025-10-20T11:40:30Z", - "formattedLastRelease": "4 weeks ago" - }, - "eerimoq/gqt": { - "hasCommitsInLast3Months": false, - "stars": 470, - "formattedStars": "470", - "license": "MIT License", - "lastRelease": "", - "formattedLastRelease": "" - }, - "Escape-Technologies/graphql-armor": { - "hasCommitsInLast3Months": false, - "stars": 553, - "formattedStars": "1k", - "license": "MIT License", - "lastRelease": "2025-08-22T13:32:40Z", - "formattedLastRelease": "2 months ago" - }, - "ldebruijn/graphql-protect": { - "hasCommitsInLast3Months": false, - "stars": 34, - "formattedStars": "34", - "license": "MIT License", - "lastRelease": "2025-09-09T20:03:39Z", - "formattedLastRelease": "2 months ago" - }, - "graphql-hive/gateway": { - "hasCommitsInLast3Months": false, - "stars": 68, - "formattedStars": "68", - "license": "MIT License", - "lastRelease": "2025-11-11T14:50:09Z", - "formattedLastRelease": "1 week ago" - }, - "microcks/microcks": { - "hasCommitsInLast3Months": false, - "stars": 1746, - "formattedStars": "2k", - "license": "Apache License 2.0", - "lastRelease": "2025-10-25T15:08:00Z", - "formattedLastRelease": "3 weeks ago" - }, - "glideapps/quicktype": { - "hasCommitsInLast3Months": false, - "stars": 13438, - "formattedStars": "13k", - "license": "Apache License 2.0", - "lastRelease": "", - "formattedLastRelease": "" - }, - "schemathesis/schemathesis": { - "hasCommitsInLast3Months": false, - "stars": 2852, - "formattedStars": "3k", - "license": "MIT License", - "lastRelease": "2025-11-18T17:07:09Z", - "formattedLastRelease": "4 hours ago" + "formattedLastRelease": "1 month ago" }, "apollographql/apollo-ios": { "hasCommitsInLast3Months": false, - "stars": 4008, + "stars": 4011, "formattedStars": "4k", "license": "MIT License", "lastRelease": "2025-11-05T23:30:57Z", - "formattedLastRelease": "1 week ago" + "formattedLastRelease": "3 weeks ago" }, "nerdsupremacist/Graphaello": { "hasCommitsInLast3Months": false, @@ -1305,7 +1241,7 @@ }, "maticzav/swift-graphql": { "hasCommitsInLast3Months": false, - "stars": 621, + "stars": 622, "formattedStars": "1k", "license": "MIT License", "lastRelease": "2024-05-06T20:00:06Z", @@ -1317,7 +1253,7 @@ "formattedStars": "1k", "license": "MIT License", "lastRelease": "2025-08-21T19:30:20Z", - "formattedLastRelease": "2 months ago" + "formattedLastRelease": "3 months ago" }, "nerdsupremacist/GraphZahl": { "hasCommitsInLast3Months": false, @@ -1327,12 +1263,76 @@ "lastRelease": "2021-05-17T12:51:10Z", "formattedLastRelease": "4 years ago" }, + "apollographql/router": { + "hasCommitsInLast3Months": false, + "stars": 939, + "formattedStars": "1k", + "license": "Other", + "lastRelease": "2025-11-28T17:47:44Z", + "formattedLastRelease": "18 hours ago" + }, + "Escape-Technologies/graphql-armor": { + "hasCommitsInLast3Months": false, + "stars": 558, + "formattedStars": "1k", + "license": "MIT License", + "lastRelease": "2025-08-22T13:32:40Z", + "formattedLastRelease": "3 months ago" + }, + "eerimoq/gqt": { + "hasCommitsInLast3Months": false, + "stars": 470, + "formattedStars": "470", + "license": "MIT License", + "lastRelease": "", + "formattedLastRelease": "" + }, + "ldebruijn/graphql-protect": { + "hasCommitsInLast3Months": false, + "stars": 34, + "formattedStars": "34", + "license": "MIT License", + "lastRelease": "2025-11-25T14:27:46Z", + "formattedLastRelease": "3 days ago" + }, + "graphql-hive/gateway": { + "hasCommitsInLast3Months": false, + "stars": 69, + "formattedStars": "69", + "license": "MIT License", + "lastRelease": "2025-11-24T15:40:17Z", + "formattedLastRelease": "4 days ago" + }, + "microcks/microcks": { + "hasCommitsInLast3Months": false, + "stars": 1754, + "formattedStars": "2k", + "license": "Apache License 2.0", + "lastRelease": "2025-10-25T15:08:00Z", + "formattedLastRelease": "1 month ago" + }, + "schemathesis/schemathesis": { + "hasCommitsInLast3Months": false, + "stars": 2871, + "formattedStars": "3k", + "license": "MIT License", + "lastRelease": "2025-11-28T16:13:29Z", + "formattedLastRelease": "19 hours ago" + }, + "glideapps/quicktype": { + "hasCommitsInLast3Months": false, + "stars": 13464, + "formattedStars": "13k", + "license": "Apache License 2.0", + "lastRelease": "", + "formattedLastRelease": "" + }, "wundergraph/cosmo": { "hasCommitsInLast3Months": false, - "stars": 1115, + "stars": 1120, "formattedStars": "1k", "license": "Apache License 2.0", - "lastRelease": "2025-11-17T21:18:03Z", + "lastRelease": "2025-11-27T13:47:56Z", "formattedLastRelease": "1 day ago" } } \ No newline at end of file diff --git a/scripts/get-github-info/last-success.isodate b/scripts/get-github-info/last-success.isodate index 27b775b3c9..817c2fe4de 100644 --- a/scripts/get-github-info/last-success.isodate +++ b/scripts/get-github-info/last-success.isodate @@ -1 +1 @@ -2025-11-18T21:48:50.765Z \ No newline at end of file +2025-11-29T12:04:08.519Z \ No newline at end of file diff --git a/scripts/sync-working-groups/working-group-events.ndjson b/scripts/sync-working-groups/working-group-events.ndjson index cfbbde9d70..012d82306e 100644 --- a/scripts/sync-working-groups/working-group-events.ndjson +++ b/scripts/sync-working-groups/working-group-events.ndjson @@ -31,3 +31,7 @@ {"kind":"calendar#event","etag":"\"3516415120288286\"","id":"h9erafl4rc1jjor9i6akokm5ec_20251218T160000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=aDllcmFmbDRyYzFqam9yOWk2YWtva201ZWNfMjAyNTEyMThUMTYwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2023-12-08T21:32:03.000Z","updated":"2025-09-18T14:59:20.144Z","summary":"GraphQL Governing Board Meeting","creator":{"email":"jburson@linuxfoundation.org"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-18T11:00:00-05:00","end":"2025-12-18T12:00:00-05:00","recurringEventId":"h9erafl4rc1jjor9i6akokm5ec","originalStartTime":{"dateTime":"2025-12-18T11:00:00-05:00","timeZone":"America/New_York"},"iCalUID":"h9erafl4rc1jjor9i6akokm5ec@google.com","sequence":3,"eventType":"default"} {"kind":"calendar#event","etag":"\"3462003372886000\"","id":"kkc5tt01ovrjv8fki1lo31g5hj_20251218T170000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=a2tjNXR0MDFvdnJqdjhma2kxbG8zMWc1aGpfMjAyNTEyMThUMTcwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2024-01-12T09:55:37.000Z","updated":"2024-11-07T17:48:06.443Z","summary":"Composite schemas WG - Weekly 3","description":"The weekly \"secondary\" meeting of the composite schemas WG: https://github.com/graphql/composite-schemas-wg

          Meeting password is \"composite\"

          Live notes are at https://docs.google.com/document/d/1hJO6U7daYvcNcQ3FBKnh3v4R256ers6M8IGyqRpY_kE/edit?usp=sharing","location":"https://zoom.us/j/91078840351","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-18T12:00:00-05:00","end":"2025-12-18T13:00:00-05:00","recurringEventId":"kkc5tt01ovrjv8fki1lo31g5hj","originalStartTime":{"dateTime":"2025-12-18T12:00:00-05:00","timeZone":"Europe/Berlin"},"iCalUID":"kkc5tt01ovrjv8fki1lo31g5hj@google.com","sequence":1,"eventType":"default"} {"kind":"calendar#event","etag":"\"3500694996844990\"","id":"2ffd8o32sh77kd3mtccrtg887n_20251218T183000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=MmZmZDhvMzJzaDc3a2QzbXRjY3J0Zzg4N25fMjAyNTEyMThUMTgzMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2025-05-01T19:23:48.000Z","updated":"2025-06-19T15:38:18.422Z","summary":"GraphQL WG - Secondary (EU)","description":"Zoom password: graphqlwg","location":"https://zoom.us/j/593263740","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-18T13:30:00-05:00","end":"2025-12-18T15:00:00-05:00","recurringEventId":"2ffd8o32sh77kd3mtccrtg887n","originalStartTime":{"dateTime":"2025-12-18T13:30:00-05:00","timeZone":"America/Los_Angeles"},"iCalUID":"2ffd8o32sh77kd3mtccrtg887n@google.com","sequence":0,"eventType":"default"} +{"kind":"calendar#event","etag":"\"3517067971709790\"","id":"f7cvs5ala9jtt147l3mik2mlvl_20251222T160000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=ZjdjdnM1YWxhOWp0dDE0N2wzbWlrMm1sdmxfMjAyNTEyMjJUMTYwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2024-01-29T15:14:17.000Z","updated":"2025-09-22T09:39:45.854Z","summary":"Conference & Community Committee Meeting - Fortnightly Recurring","description":"\nYou have been invited to a recurring meeting for GraphQL Foundation\n\nWeekly Sync and Coordination Meeting for Conference Committee participants. Notes Document: https://docs.google.com/document/d/19-alP5jywnXzgN_1zYLBTRWh-4CaXzGakEZdTBFwNAc/edit\n\nWays to join meeting:\n\n1. Join from PC, Mac, iPad, or Android\n\nhttps://zoom-lfx.platform.linuxfoundation.org/meeting/96286151238?password=ff267735-efbd-4be4-a89c-b927b596190a\n\n2. Join via audio\n\nOne tap mobile:\nUS: +12532158782,,96286151238# or +13462487799,,96286151238\n\nOr dial:\nUS: +1 253 215 8782 or +1 346 248 7799 or +1 669 900 6833 or +1 301 715 8592 or +1 312 626 6799 or +1 646 374 8656 or 877 369 0926 (Toll Free) or 855 880 1246 (Toll Free)\nCanada: +1 647 374 4685 or +1 647 558 0588 or +1 778 907 2071 or +1 204 272 7920 or +1 438 809 7799 or +1 587 328 1099 or 855 703 8985 (Toll Free)\n\nMeeting ID: 96286151238\n\nMeeting Passcode: 986182\n\n\nInternational numbers: https://zoom.us/u/alwnPIaVT\n","location":"https://zoom-lfx.platform.linuxfoundation.org/meeting/96286151238?password=ff267735-efbd-4be4-a89c-b927b596190a","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-22T11:00:00-05:00","end":"2025-12-22T12:00:00-05:00","recurringEventId":"f7cvs5ala9jtt147l3mik2mlvl","originalStartTime":{"dateTime":"2025-12-22T11:00:00-05:00","timeZone":"America/New_York"},"iCalUID":"f7cvs5ala9jtt147l3mik2mlvl@google.com","sequence":2,"guestsCanInviteOthers":false,"eventType":"default"} +{"kind":"calendar#event","etag":"\"3524923598591262\"","id":"s9agipg1r702pfngano7pol2h5_20251225T170000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=czlhZ2lwZzFyNzAycGZuZ2Fubzdwb2wyaDVfMjAyNTEyMjVUMTcwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2024-01-12T09:56:07.000Z","updated":"2025-11-06T20:43:19.295Z","summary":"Composite schemas WG - Weekly 4","description":"The weekly "secondary" meeting of the composite schemas WG: https://github.com/graphql/composite-schemas-wg

          Meeting password is "composite"

          Live notes are at https://docs.google.com/document/d/1hJO6U7daYvcNcQ3FBKnh3v4R256ers6M8IGyqRpY_kE/edit?usp=sharing","location":"https://zoom.us/j/91078840351","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-25T12:00:00-05:00","end":"2025-12-25T13:00:00-05:00","recurringEventId":"s9agipg1r702pfngano7pol2h5","originalStartTime":{"dateTime":"2025-12-25T12:00:00-05:00","timeZone":"Europe/Berlin"},"iCalUID":"s9agipg1r702pfngano7pol2h5@google.com","sequence":1,"eventType":"default"} +{"kind":"calendar#event","etag":"\"3524923550687710\"","id":"4igp67o2j2nkso49c1d6nbv040_20251225T180000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=NGlncDY3bzJqMm5rc280OWMxZDZuYnYwNDBfMjAyNTEyMjVUMTgwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2025-04-15T10:29:33.000Z","updated":"2025-11-06T20:42:55.343Z","summary":"GraphQL OTel WG","description":"Zoom password: otel
           
          https://github.com/graphql/otel-wg","location":"https://zoom.us/j/93594710848?pwd=meEB8rd5g69r5DF8zFaL8VIWO2Il1v.1","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-25T13:00:00-05:00","end":"2025-12-25T14:00:00-05:00","recurringEventId":"4igp67o2j2nkso49c1d6nbv040","originalStartTime":{"dateTime":"2025-12-25T13:00:00-05:00","timeZone":"America/Los_Angeles"},"iCalUID":"4igp67o2j2nkso49c1d6nbv040@google.com","sequence":0,"eventType":"default"} +{"kind":"calendar#event","etag":"\"3524923616454910\"","id":"pag44b4o3k87r90laj5vf5t67v_20251225T190000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=cGFnNDRiNG8zazg3cjkwbGFqNXZmNXQ2N3ZfMjAyNTEyMjVUMTkwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2023-12-04T10:48:14.000Z","updated":"2025-11-06T20:43:28.227Z","summary":"GraphQL-over-HTTP WG","description":"Zoom password: httpwg","location":"https://zoom.us/j/92781382543","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-25T14:00:00-05:00","end":"2025-12-25T15:00:00-05:00","recurringEventId":"pag44b4o3k87r90laj5vf5t67v","originalStartTime":{"dateTime":"2025-12-25T14:00:00-05:00","timeZone":"America/Los_Angeles"},"iCalUID":"pag44b4o3k87r90laj5vf5t67v@google.com","sequence":3,"eventType":"default"} From 3f1be057e7718c3bfa8454ccd5103700742320ad Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 13:11:25 +0100 Subject: [PATCH 45/58] Add backgrounds to TOC footer --- src/components/table-of-contents.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/table-of-contents.tsx b/src/components/table-of-contents.tsx index 602ecd0924..0f8ca9af8f 100644 --- a/src/components/table-of-contents.tsx +++ b/src/components/table-of-contents.tsx @@ -101,7 +101,8 @@ export function TableOfContents({ {hasMetaInfo && (
          Date: Sat, 29 Nov 2025 13:11:35 +0100 Subject: [PATCH 46/58] wip --- .../learn-aggregator/common-questions.tsx | 15 +++++------ src/pages/faq/_meta.ts | 17 +++++------- src/pages/faq/index.mdx | 27 ++++++++++--------- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/components/learn-aggregator/common-questions.tsx b/src/components/learn-aggregator/common-questions.tsx index 7cafe1d814..d3013c7de9 100644 --- a/src/components/learn-aggregator/common-questions.tsx +++ b/src/components/learn-aggregator/common-questions.tsx @@ -25,19 +25,16 @@ export function CommonQuestionsSection(
            - + - - - + + +
          ) diff --git a/src/pages/faq/_meta.ts b/src/pages/faq/_meta.ts index db8b2a9b62..93911a07d8 100644 --- a/src/pages/faq/_meta.ts +++ b/src/pages/faq/_meta.ts @@ -1,14 +1,11 @@ export default { index: { - title: "Overview", - theme: { - toc: false, - }, + title: "FAQ", }, - "getting-started": "", - general: "", - "best-practices": "", - specification: "", - frontend: "", - foundation: "", + "getting-started": { display: "hidden" }, + general: { display: "hidden" }, + "best-practices": { display: "hidden" }, + specification: { display: "hidden" }, + frontend: { display: "hidden" }, + foundation: { display: "hidden" }, } diff --git a/src/pages/faq/index.mdx b/src/pages/faq/index.mdx index 2a0a6574ef..6623adac26 100644 --- a/src/pages/faq/index.mdx +++ b/src/pages/faq/index.mdx @@ -1,14 +1,17 @@ -import { Cards } from 'nextra/components' -import metaFile from './_meta' +import { FaqAggregator, faqMdxComponents } from "@/components/faq-aggregator" -# Frequently Asked Questions (FAQ) +import GettingStarted from "./getting-started.mdx" +import General from "./general.mdx" +import BestPractices from "./best-practices.mdx" +import Specification from "./specification.mdx" +import Frontend from "./frontend.mdx" +import Foundation from "./foundation.mdx" - - {Object.entries(metaFile).slice(1).map(([key]) => ( - word[0].toUpperCase() + word.slice(1)).join(' ')} - href={`/faq/${key}`} arrow - /> - ))} - +

          Frequently Asked Questions

          + + + + + + + From 2d35b037fa657fff1a2c2e99a3f6f103815602c5 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 13:27:39 +0100 Subject: [PATCH 47/58] Aggregate all FAQ pages on one page as per design --- src/components/faq-aggregator/index.tsx | 101 ++++++++++++++++++++++++ src/pages/faq/_meta.ts | 4 + src/pages/faq/index.mdx | 14 ++-- 3 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 src/components/faq-aggregator/index.tsx diff --git a/src/components/faq-aggregator/index.tsx b/src/components/faq-aggregator/index.tsx new file mode 100644 index 0000000000..d2efb9b1c3 --- /dev/null +++ b/src/components/faq-aggregator/index.tsx @@ -0,0 +1,101 @@ +"use client" + +import { type ReactNode, useRef, useLayoutEffect, useState } from "react" + +function slugify(text: string): string { + return String(text) + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, "") +} + +function FaqH1({ id, children }: { id?: string; children?: ReactNode }) { + const slug = id ?? slugify(String(children)) + return ( +

          + + {children} + +

          + ) +} + +function FaqH2({ id, children }: { id?: string; children?: ReactNode }) { + const slug = id ?? slugify(String(children)) + return ( +
          + +

          + {children} +

          + +
          +
          + ) +} + +function ChevronIcon({ className }: { className?: string }) { + return ( + + + + ) +} + +export function FaqAggregator({ children }: { children: ReactNode }) { + const containerRef = useRef(null) + const [, forceUpdate] = useState(0) + + useLayoutEffect(() => { + const container = containerRef.current + if (!container) return + + const details = container.querySelectorAll("details") + details.forEach(detail => { + const answerContent: Node[] = [] + let sibling = detail.nextSibling + + while (sibling) { + const next = sibling.nextSibling + if (sibling instanceof Element) { + if (sibling.tagName === "DETAILS" || sibling.tagName === "H2") break + answerContent.push(sibling) + } else if ( + sibling.nodeType === Node.TEXT_NODE && + sibling.textContent?.trim() + ) { + answerContent.push(sibling) + } + sibling = next + } + + if (answerContent.length > 0) { + const wrapper = document.createElement("div") + wrapper.className = "pb-4" + answerContent.forEach(node => wrapper.appendChild(node)) + detail.appendChild(wrapper) + } + }) + + forceUpdate(n => n + 1) + }, []) + + return
          {children}
          +} + +export const faqMdxComponents = { + h1: FaqH1, + h2: FaqH2, +} diff --git a/src/pages/faq/_meta.ts b/src/pages/faq/_meta.ts index 93911a07d8..db899ed7f1 100644 --- a/src/pages/faq/_meta.ts +++ b/src/pages/faq/_meta.ts @@ -1,6 +1,10 @@ export default { index: { title: "FAQ", + theme: { + toc: false, + sidebar: false, + }, }, "getting-started": { display: "hidden" }, general: { display: "hidden" }, diff --git a/src/pages/faq/index.mdx b/src/pages/faq/index.mdx index 6623adac26..a4b03fc37a 100644 --- a/src/pages/faq/index.mdx +++ b/src/pages/faq/index.mdx @@ -9,9 +9,11 @@ import Foundation from "./foundation.mdx"

          Frequently Asked Questions

          - - - - - - + + + + + + + + From 31945af61080cb49a7fe22fb90e2d5196b8d2634 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 13:31:35 +0100 Subject: [PATCH 48/58] Format icons --- .../decorations/best-practices.svg | 17 +++++++++++ .../faq-aggregator/decorations/frontend.svg | 17 +++++++++++ .../faq-aggregator/decorations/general.svg | 21 +++++++++++++ .../decorations/getting-started.svg | 17 +++++++++++ .../decorations/specification.svg | 17 +++++++++++ .../learn-aggregator/assets/books.svg | 20 ++++++++++++- .../learn-aggregator/assets/checkbox.svg | 17 ++++++++++- .../learn-aggregator/assets/circuit.svg | 20 ++++++++++++- .../learn-aggregator/assets/cog-double.svg | 30 ++++++++++++++++++- .../learn-aggregator/assets/computer.svg | 20 ++++++++++++- .../learn-aggregator/assets/construction.svg | 23 +++++++++++++- .../learn-aggregator/assets/dna.svg | 23 +++++++++++++- .../learn-aggregator/assets/globe.svg | 26 +++++++++++++++- .../learn-aggregator/assets/hierarchy.svg | 26 +++++++++++++++- .../learn-aggregator/assets/key.svg | 23 +++++++++++++- .../learn-aggregator/assets/layer.svg | 25 +++++++++++++++- .../assets/nav-left-circle.svg | 23 +++++++++++++- .../learn-aggregator/assets/note.svg | 20 ++++++++++++- .../learn-aggregator/assets/product-check.svg | 17 ++++++++++- .../learn-aggregator/assets/safe.svg | 20 ++++++++++++- .../learn-aggregator/assets/search.svg | 17 ++++++++++- .../learn-aggregator/assets/share.svg | 26 +++++++++++++++- .../learn-aggregator/assets/solve.svg | 18 ++++++++++- .../learn-aggregator/assets/startup.svg | 24 ++++++++++++++- .../learn-aggregator/assets/sync-square.svg | 17 ++++++++++- .../learn-aggregator/assets/zoom-page.svg | 20 ++++++++++++- 26 files changed, 523 insertions(+), 21 deletions(-) create mode 100644 src/components/faq-aggregator/decorations/best-practices.svg create mode 100644 src/components/faq-aggregator/decorations/frontend.svg create mode 100644 src/components/faq-aggregator/decorations/general.svg create mode 100644 src/components/faq-aggregator/decorations/getting-started.svg create mode 100644 src/components/faq-aggregator/decorations/specification.svg diff --git a/src/components/faq-aggregator/decorations/best-practices.svg b/src/components/faq-aggregator/decorations/best-practices.svg new file mode 100644 index 0000000000..ead38a4597 --- /dev/null +++ b/src/components/faq-aggregator/decorations/best-practices.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/decorations/frontend.svg b/src/components/faq-aggregator/decorations/frontend.svg new file mode 100644 index 0000000000..5b1be09991 --- /dev/null +++ b/src/components/faq-aggregator/decorations/frontend.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/decorations/general.svg b/src/components/faq-aggregator/decorations/general.svg new file mode 100644 index 0000000000..5285544d76 --- /dev/null +++ b/src/components/faq-aggregator/decorations/general.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/components/faq-aggregator/decorations/getting-started.svg b/src/components/faq-aggregator/decorations/getting-started.svg new file mode 100644 index 0000000000..853ff0bb18 --- /dev/null +++ b/src/components/faq-aggregator/decorations/getting-started.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/decorations/specification.svg b/src/components/faq-aggregator/decorations/specification.svg new file mode 100644 index 0000000000..586bf85db4 --- /dev/null +++ b/src/components/faq-aggregator/decorations/specification.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/learn-aggregator/assets/books.svg b/src/components/learn-aggregator/assets/books.svg index b28d4f9656..08ba62271a 100644 --- a/src/components/learn-aggregator/assets/books.svg +++ b/src/components/learn-aggregator/assets/books.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/checkbox.svg b/src/components/learn-aggregator/assets/checkbox.svg index 2fc41369cb..432abbaee5 100644 --- a/src/components/learn-aggregator/assets/checkbox.svg +++ b/src/components/learn-aggregator/assets/checkbox.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + diff --git a/src/components/learn-aggregator/assets/circuit.svg b/src/components/learn-aggregator/assets/circuit.svg index df7625bffe..2324822e55 100644 --- a/src/components/learn-aggregator/assets/circuit.svg +++ b/src/components/learn-aggregator/assets/circuit.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/cog-double.svg b/src/components/learn-aggregator/assets/cog-double.svg index a169230ab5..0e8f272a77 100644 --- a/src/components/learn-aggregator/assets/cog-double.svg +++ b/src/components/learn-aggregator/assets/cog-double.svg @@ -1 +1,29 @@ - \ No newline at end of file + + + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/computer.svg b/src/components/learn-aggregator/assets/computer.svg index 49980390b9..2ea9a797c6 100644 --- a/src/components/learn-aggregator/assets/computer.svg +++ b/src/components/learn-aggregator/assets/computer.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/construction.svg b/src/components/learn-aggregator/assets/construction.svg index 87ea57c465..a3a332693e 100644 --- a/src/components/learn-aggregator/assets/construction.svg +++ b/src/components/learn-aggregator/assets/construction.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/dna.svg b/src/components/learn-aggregator/assets/dna.svg index 4914769413..bdf4234af5 100644 --- a/src/components/learn-aggregator/assets/dna.svg +++ b/src/components/learn-aggregator/assets/dna.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/globe.svg b/src/components/learn-aggregator/assets/globe.svg index 17f6cb543d..731792c5a9 100644 --- a/src/components/learn-aggregator/assets/globe.svg +++ b/src/components/learn-aggregator/assets/globe.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/hierarchy.svg b/src/components/learn-aggregator/assets/hierarchy.svg index f907687b01..ed0bcc4767 100644 --- a/src/components/learn-aggregator/assets/hierarchy.svg +++ b/src/components/learn-aggregator/assets/hierarchy.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/key.svg b/src/components/learn-aggregator/assets/key.svg index a5792cc894..74eb5cb72a 100644 --- a/src/components/learn-aggregator/assets/key.svg +++ b/src/components/learn-aggregator/assets/key.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/layer.svg b/src/components/learn-aggregator/assets/layer.svg index 54b7bb9542..2730903094 100644 --- a/src/components/learn-aggregator/assets/layer.svg +++ b/src/components/learn-aggregator/assets/layer.svg @@ -1 +1,24 @@ - \ No newline at end of file + + + + + + diff --git a/src/components/learn-aggregator/assets/nav-left-circle.svg b/src/components/learn-aggregator/assets/nav-left-circle.svg index 3b568b6fdd..395b0b562e 100644 --- a/src/components/learn-aggregator/assets/nav-left-circle.svg +++ b/src/components/learn-aggregator/assets/nav-left-circle.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/note.svg b/src/components/learn-aggregator/assets/note.svg index 39e0de7c52..90b81e393d 100644 --- a/src/components/learn-aggregator/assets/note.svg +++ b/src/components/learn-aggregator/assets/note.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/product-check.svg b/src/components/learn-aggregator/assets/product-check.svg index 046554e4cd..b5ffbd2670 100644 --- a/src/components/learn-aggregator/assets/product-check.svg +++ b/src/components/learn-aggregator/assets/product-check.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + diff --git a/src/components/learn-aggregator/assets/safe.svg b/src/components/learn-aggregator/assets/safe.svg index 93f832daee..093727d0de 100644 --- a/src/components/learn-aggregator/assets/safe.svg +++ b/src/components/learn-aggregator/assets/safe.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/search.svg b/src/components/learn-aggregator/assets/search.svg index c52d9f08b7..3f824bc454 100644 --- a/src/components/learn-aggregator/assets/search.svg +++ b/src/components/learn-aggregator/assets/search.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + + + + + diff --git a/src/components/learn-aggregator/assets/share.svg b/src/components/learn-aggregator/assets/share.svg index 6567793f34..af002cf99c 100644 --- a/src/components/learn-aggregator/assets/share.svg +++ b/src/components/learn-aggregator/assets/share.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/solve.svg b/src/components/learn-aggregator/assets/solve.svg index 0479304299..0705b3eba7 100644 --- a/src/components/learn-aggregator/assets/solve.svg +++ b/src/components/learn-aggregator/assets/solve.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + diff --git a/src/components/learn-aggregator/assets/startup.svg b/src/components/learn-aggregator/assets/startup.svg index ee982cf48f..2fa142a43b 100644 --- a/src/components/learn-aggregator/assets/startup.svg +++ b/src/components/learn-aggregator/assets/startup.svg @@ -1 +1,23 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/sync-square.svg b/src/components/learn-aggregator/assets/sync-square.svg index 1931355fad..d6d9b7b34b 100644 --- a/src/components/learn-aggregator/assets/sync-square.svg +++ b/src/components/learn-aggregator/assets/sync-square.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + + + + + diff --git a/src/components/learn-aggregator/assets/zoom-page.svg b/src/components/learn-aggregator/assets/zoom-page.svg index 9680c94c26..81e62c9a4f 100644 --- a/src/components/learn-aggregator/assets/zoom-page.svg +++ b/src/components/learn-aggregator/assets/zoom-page.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + From 4f9d0caef50dd3e89cfc84f31d508b09492fe39b Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 14:44:49 +0100 Subject: [PATCH 49/58] Show a shorter TOC --- src/components/nextra-mdx-wrapper.tsx | 5 +++++ src/pages/faq/_meta.ts | 24 +++++++++++++++++------- src/pages/faq/index.mdx | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/components/nextra-mdx-wrapper.tsx b/src/components/nextra-mdx-wrapper.tsx index 83dde0bfa4..c2f4e4461e 100644 --- a/src/components/nextra-mdx-wrapper.tsx +++ b/src/components/nextra-mdx-wrapper.tsx @@ -36,6 +36,11 @@ export function NextraMdxWrapper({ directories, } = config.normalizePagesResult + console.log(themeContext.toc) + if (themeContext.toc && typeof themeContext.toc === "object") { + toc = themeContext.toc + } + const tocEl = activeType === "page" || !themeContext.toc || diff --git a/src/pages/faq/_meta.ts b/src/pages/faq/_meta.ts index db899ed7f1..532f762bb3 100644 --- a/src/pages/faq/_meta.ts +++ b/src/pages/faq/_meta.ts @@ -1,15 +1,25 @@ export default { index: { title: "FAQ", + type: "hidden", theme: { - toc: false, sidebar: false, + timestamp: false, + breadcrumb: false, + toc: [ + { value: "Getting Started", id: "getting-started", depth: 2 }, + { value: "General", id: "general", depth: 2 }, + { value: "Best Practices", id: "best-practices", depth: 2 }, + { value: "Specification", id: "specification", depth: 2 }, + { value: "Frontend", id: "frontend", depth: 2 }, + { value: "Foundation", id: "foundation", depth: 2 }, + ], }, }, - "getting-started": { display: "hidden" }, - general: { display: "hidden" }, - "best-practices": { display: "hidden" }, - specification: { display: "hidden" }, - frontend: { display: "hidden" }, - foundation: { display: "hidden" }, + "getting-started": "", + general: "", + "best-practices": "", + specification: "", + frontend: "", + foundation: "", } diff --git a/src/pages/faq/index.mdx b/src/pages/faq/index.mdx index a4b03fc37a..f0e461631c 100644 --- a/src/pages/faq/index.mdx +++ b/src/pages/faq/index.mdx @@ -7,7 +7,7 @@ import Specification from "./specification.mdx" import Frontend from "./frontend.mdx" import Foundation from "./foundation.mdx" -

          Frequently Asked Questions

          +

          Frequently Asked Questions

          From 9a30e04af1a4a3ee19bf2165c0b8590ce1d07e9a Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 14:45:49 +0100 Subject: [PATCH 50/58] Always white text on primary background --- src/components/learn-aggregator/looking-for-more.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/learn-aggregator/looking-for-more.tsx b/src/components/learn-aggregator/looking-for-more.tsx index 768aaa62da..95c719ad66 100644 --- a/src/components/learn-aggregator/looking-for-more.tsx +++ b/src/components/learn-aggregator/looking-for-more.tsx @@ -7,7 +7,7 @@ export function LookingForMore(props: React.HTMLAttributes) { {...props} className={clsx("gql-container gql-section", props.className)} > -
          +

          Looking for more?

          From 240c6e69b1a992c6d992a1ff3db96bed49f8abb0 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 14:45:57 +0100 Subject: [PATCH 51/58] Remove redundant margin --- src/components/faq-aggregator/index.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/faq-aggregator/index.tsx b/src/components/faq-aggregator/index.tsx index d2efb9b1c3..41e4c0e993 100644 --- a/src/components/faq-aggregator/index.tsx +++ b/src/components/faq-aggregator/index.tsx @@ -26,7 +26,7 @@ function FaqH1({ id, children }: { id?: string; children?: ReactNode }) { function FaqH2({ id, children }: { id?: string; children?: ReactNode }) { const slug = id ?? slugify(String(children)) return ( -

          +

          {children} @@ -82,10 +82,7 @@ export function FaqAggregator({ children }: { children: ReactNode }) { } if (answerContent.length > 0) { - const wrapper = document.createElement("div") - wrapper.className = "pb-4" - answerContent.forEach(node => wrapper.appendChild(node)) - detail.appendChild(wrapper) + answerContent.forEach(node => detail.appendChild(node)) } }) From 6269378ff99e8365bfcfbd1b271cebe83c37b0c6 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 14:53:49 +0100 Subject: [PATCH 52/58] Highlight current heading --- .../mdx-components/get-mdx-headings.tsx | 6 ++++-- src/components/faq-aggregator/index.tsx | 14 ++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/_design-system/mdx-components/get-mdx-headings.tsx b/src/_design-system/mdx-components/get-mdx-headings.tsx index a162126a90..0f5eb88bde 100644 --- a/src/_design-system/mdx-components/get-mdx-headings.tsx +++ b/src/_design-system/mdx-components/get-mdx-headings.tsx @@ -30,7 +30,9 @@ const createHeading = ( id, className, ...props - }: React.ComponentPropsWithoutRef<"h2">): React.ReactElement { + }: React.ComponentPropsWithoutRef<"h2"> & { + size?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" + }): React.ReactElement { // Nextra tracks anchors in context const setActiveAnchor = useSetActiveAnchor() const slugs = useSlugs() @@ -61,7 +63,7 @@ const createHeading = ( className === "sr-only" ? // can be added by footnotes "sr-only" - : clsx(headingClasses[Tag], "text-neu-900", className) + : clsx(headingClasses[props.size || Tag], "text-neu-900", className) } {...props} > diff --git a/src/components/faq-aggregator/index.tsx b/src/components/faq-aggregator/index.tsx index 41e4c0e993..9ee1f94958 100644 --- a/src/components/faq-aggregator/index.tsx +++ b/src/components/faq-aggregator/index.tsx @@ -1,5 +1,6 @@ "use client" +import { getMdxHeadings } from "@/_design-system/mdx-components/get-mdx-headings" import { type ReactNode, useRef, useLayoutEffect, useState } from "react" function slugify(text: string): string { @@ -9,17 +10,18 @@ function slugify(text: string): string { .replace(/(^-|-$)/g, "") } +const mdxHeadings = getMdxHeadings() + function FaqH1({ id, children }: { id?: string; children?: ReactNode }) { const slug = id ?? slugify(String(children)) return ( -

          - - {children} - -

          + {children} + ) } From e937a8c8dbfe37aeabc035e9733b5844bb4d7a38 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 15:04:07 +0100 Subject: [PATCH 53/58] Style questions --- src/components/faq-aggregator/index.tsx | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/components/faq-aggregator/index.tsx b/src/components/faq-aggregator/index.tsx index 9ee1f94958..109ded5e10 100644 --- a/src/components/faq-aggregator/index.tsx +++ b/src/components/faq-aggregator/index.tsx @@ -2,6 +2,7 @@ import { getMdxHeadings } from "@/_design-system/mdx-components/get-mdx-headings" import { type ReactNode, useRef, useLayoutEffect, useState } from "react" +import ArrowDown from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" function slugify(text: string): string { return String(text) @@ -28,34 +29,17 @@ function FaqH1({ id, children }: { id?: string; children?: ReactNode }) { function FaqH2({ id, children }: { id?: string; children?: ReactNode }) { const slug = id ?? slugify(String(children)) return ( -
          - +
          +

          {children}

          - +
          ) } -function ChevronIcon({ className }: { className?: string }) { - return ( - - - - ) -} - export function FaqAggregator({ children }: { children: ReactNode }) { const containerRef = useRef(null) const [, forceUpdate] = useState(0) From 34a97fa6f7315a7c712723c547c9cf695a57fbc0 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 15:38:03 +0100 Subject: [PATCH 54/58] Add icons --- src/components/faq-aggregator/index.tsx | 45 ++++++++++++++++++++----- src/components/table-of-contents.tsx | 2 +- src/nextra-theme-docs.css | 2 +- src/pages/faq/index.mdx | 4 +++ src/pages/learn/index.mdx | 4 +++ 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/components/faq-aggregator/index.tsx b/src/components/faq-aggregator/index.tsx index 109ded5e10..84509b9e5d 100644 --- a/src/components/faq-aggregator/index.tsx +++ b/src/components/faq-aggregator/index.tsx @@ -3,6 +3,11 @@ import { getMdxHeadings } from "@/_design-system/mdx-components/get-mdx-headings" import { type ReactNode, useRef, useLayoutEffect, useState } from "react" import ArrowDown from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" +import BestPracticesIcon from "./decorations/best-practices.svg?svgr" +import FrontendIcon from "./decorations/frontend.svg?svgr" +import GeneralIcon from "./decorations/general.svg?svgr" +import GettingStartedIcon from "./decorations/getting-started.svg?svgr" +import SpecificationIcon from "./decorations/specification.svg?svgr" function slugify(text: string): string { return String(text) @@ -13,24 +18,42 @@ function slugify(text: string): string { const mdxHeadings = getMdxHeadings() +const iconMap: Record = { + "getting-started": GettingStartedIcon, + "best-practices": BestPracticesIcon, + frontend: FrontendIcon, + general: GeneralIcon, + specification: SpecificationIcon, +} + function FaqH1({ id, children }: { id?: string; children?: ReactNode }) { const slug = id ?? slugify(String(children)) + const Icon = iconMap[slug] ?? GeneralIcon + return ( - - {children} - +
          + +
          + + {children} + +

          ) } function FaqH2({ id, children }: { id?: string; children?: ReactNode }) { const slug = id ?? slugify(String(children)) return ( -
          - +
          +

          {children}

          @@ -56,7 +79,11 @@ export function FaqAggregator({ children }: { children: ReactNode }) { while (sibling) { const next = sibling.nextSibling if (sibling instanceof Element) { - if (sibling.tagName === "DETAILS" || sibling.tagName === "H2") break + if ( + sibling.tagName === "DETAILS" || + (sibling as HTMLElement).dataset?.heading + ) + break answerContent.push(sibling) } else if ( sibling.nodeType === Node.TEXT_NODE && diff --git a/src/components/table-of-contents.tsx b/src/components/table-of-contents.tsx index 0f8ca9af8f..84c3460434 100644 --- a/src/components/table-of-contents.tsx +++ b/src/components/table-of-contents.tsx @@ -86,7 +86,7 @@ export function TableOfContents({ }[depth], "block", activeAnchor[id]?.isActive - ? "text-pri-base contrast-more:!text-pri-base" + ? "text-pri-base contrast-more:!text-pri-base dark:text-pri-light" : "", )} > diff --git a/src/nextra-theme-docs.css b/src/nextra-theme-docs.css index 9b3d03e932..5f8993280a 100644 --- a/src/nextra-theme-docs.css +++ b/src/nextra-theme-docs.css @@ -1585,7 +1585,7 @@ pre } :target > .subheading-anchor:is(html[class~="dark"] *):after { --tw-text-opacity: 1; - color: rgb(115 115 115 / var(--tw-text-opacity, 1)); + color: rgb(110 117 87 / var(--tw-text-opacity, 1)); } .subheading-anchor:after { --tw-content: "#"; diff --git a/src/pages/faq/index.mdx b/src/pages/faq/index.mdx index f0e461631c..0882acaec0 100644 --- a/src/pages/faq/index.mdx +++ b/src/pages/faq/index.mdx @@ -1,3 +1,7 @@ +--- +title: FAQ +--- + import { FaqAggregator, faqMdxComponents } from "@/components/faq-aggregator" import GettingStarted from "./getting-started.mdx" diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index e3462ff6a9..b2187f13d2 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -1,3 +1,7 @@ +--- +title: Learn +--- + import { Button } from '@/app/conf/_design-system/button'; import { NavbarFixed } from '../../components/navbar/navbar-fixed' From 4086a9d1a553cbc7ab90cec362ac5d614ff741e5 Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 15:40:53 +0100 Subject: [PATCH 55/58] Remove console.log --- src/components/nextra-mdx-wrapper.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/nextra-mdx-wrapper.tsx b/src/components/nextra-mdx-wrapper.tsx index c2f4e4461e..4dc9b4fc2f 100644 --- a/src/components/nextra-mdx-wrapper.tsx +++ b/src/components/nextra-mdx-wrapper.tsx @@ -36,7 +36,6 @@ export function NextraMdxWrapper({ directories, } = config.normalizePagesResult - console.log(themeContext.toc) if (themeContext.toc && typeof themeContext.toc === "object") { toc = themeContext.toc } From f3b2cad131ba41573f2d4557ed6c07be26c7413b Mon Sep 17 00:00:00 2001 From: Piotr Monwid-Olechnowicz Date: Sat, 29 Nov 2025 15:54:00 +0100 Subject: [PATCH 56/58] Mirror .reverse() call from `source` --- src/app/(main)/community/events/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/(main)/community/events/page.tsx b/src/app/(main)/community/events/page.tsx index f5e2c36f78..7282f0bd53 100644 --- a/src/app/(main)/community/events/page.tsx +++ b/src/app/(main)/community/events/page.tsx @@ -89,7 +89,7 @@ export default async function EventsPage() { Add a new event - +