diff --git a/next.config.js b/next.config.js
index 56da077fae..3a99e7137e 100644
--- a/next.config.js
+++ b/next.config.js
@@ -37,7 +37,7 @@ const ALLOWED_SVG_REGEX = new RegExp(`${sep}icons${sep}.+\\.svg$`)
const config = {
output: undefined,
// reactStrictMode: true, provoke duplicated codemirror editors
- webpack(config) {
+ webpack(config, { isServer, dev }) {
// #region MDX
const mdxRule = config.module.rules.find(rule => rule.test?.test?.(".mdx"))
if (mdxRule) {
@@ -62,6 +62,19 @@ const config = {
fileLoaderRule.exclude = /\.svg$/i
config.module.rules.push(
+ {
+ test: /\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg|txt)$/i,
+ resourceQuery: /resource/,
+ type: "asset/resource",
+ generator: {
+ filename: "static/media/[name].[hash][ext]",
+ publicPath: "/_next/",
+ // Server build outputs to .next/server/, so go up to reach .next/static/
+ outputPath: [isServer && "../", !dev && "../"]
+ .filter(Boolean)
+ .join(""),
+ },
+ },
// All .svg from /icons/ and with ?svgr are going to be processed by @svgr/webpack
{
test: ALLOWED_SVG_REGEX,
@@ -103,7 +116,7 @@ const config = {
test: /\.svg$/i,
exclude: ALLOWED_SVG_REGEX,
resourceQuery: {
- not: [...fileLoaderRule.resourceQuery.not, /svgr/],
+ not: [...fileLoaderRule.resourceQuery.not, /svgr|resource/],
},
},
)
diff --git a/package.json b/package.json
index d3b9d07d11..1d3a6faff6 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/nesting": "0.0.0-insiders.565cd3e",
"@tailwindcss/typography": "^0.5.15",
+ "arktype": "2.1.28",
"autoprefixer": "^10.4.20",
"calendar-link": "^2.10.0",
"clsx": "^2.1.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d4a166532a..3f04a3c7a1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -83,6 +83,9 @@ importers:
'@tailwindcss/typography':
specifier: ^0.5.15
version: 0.5.19(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.1))
+ arktype:
+ specifier: 2.1.28
+ version: 2.1.28
autoprefixer:
specifier: ^10.4.20
version: 10.4.22(postcss@8.5.6)
@@ -326,8 +329,8 @@ importers:
scripts/sync-working-groups:
dependencies:
arktype:
- specifier: ^2.1.27
- version: 2.1.29
+ specifier: 2.1.28
+ version: 2.1.28
packages:
@@ -2663,11 +2666,11 @@ packages:
aria-query@5.3.0:
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
- arkregex@0.0.5:
- resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==}
+ arkregex@0.0.4:
+ resolution: {integrity: sha512-biS/FkvSwQq59TZ453piUp8bxMui11pgOMV9WHAnli1F8o0ayNCZzUwQadL/bGIUic5TkS/QlPcyMuI8ZIwedQ==}
- arktype@2.1.29:
- resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==}
+ arktype@2.1.28:
+ resolution: {integrity: sha512-LVZqXl2zWRpNFnbITrtFmqeqNkPPo+KemuzbGSY6jvJwCb4v8NsDzrWOLHnQgWl26TkJeWWcUNUeBpq2Mst1/Q==}
array-buffer-byte-length@1.0.2:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
@@ -9415,15 +9418,15 @@ snapshots:
dependencies:
dequal: 2.0.3
- arkregex@0.0.5:
+ arkregex@0.0.4:
dependencies:
'@ark/util': 0.56.0
- arktype@2.1.29:
+ arktype@2.1.28:
dependencies:
'@ark/schema': 0.56.0
'@ark/util': 0.56.0
- arkregex: 0.0.5
+ arkregex: 0.0.4
array-buffer-byte-length@1.0.2:
dependencies:
diff --git a/scripts/get-github-info/github-stats.json b/scripts/get-github-info/github-stats.json
index 9f6b835af8..dae0f6bf92 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": 5365,
+ "stars": 5372,
"formattedStars": "5k",
"license": "MIT License",
- "lastRelease": "2025-10-28T22:43:22Z",
- "formattedLastRelease": "1 month ago"
+ "lastRelease": "2025-12-12T08:48:15Z",
+ "formattedLastRelease": "12 hours ago"
},
"apache/apisix": {
"hasCommitsInLast3Months": false,
- "stars": 15907,
+ "stars": 15968,
"formattedStars": "16k",
"license": "Apache License 2.0",
"lastRelease": "2025-10-16T07:54:57Z",
@@ -17,27 +17,27 @@
},
"apollographql/apollo-studio-community": {
"hasCommitsInLast3Months": false,
- "stars": 261,
- "formattedStars": "261",
+ "stars": 260,
+ "formattedStars": "260",
"license": "Unknown",
"lastRelease": "",
"formattedLastRelease": ""
},
"ChilliCream/hotchocolate": {
"hasCommitsInLast3Months": false,
- "stars": 5637,
+ "stars": 5650,
"formattedStars": "6k",
"license": "MIT License",
- "lastRelease": "2025-11-26T11:12:44Z",
- "formattedLastRelease": "3 days ago"
+ "lastRelease": "2025-12-10T12:55:40Z",
+ "formattedLastRelease": "2 days ago"
},
"dgraph-io/dgraph": {
"hasCommitsInLast3Months": false,
- "stars": 21367,
+ "stars": 21392,
"formattedStars": "21k",
"license": "Apache License 2.0",
- "lastRelease": "2025-10-07T20:50:36Z",
- "formattedLastRelease": "1 month ago"
+ "lastRelease": "2025-12-12T00:45:30Z",
+ "formattedLastRelease": "20 hours ago"
},
"yahoo/elide": {
"hasCommitsInLast3Months": false,
@@ -45,7 +45,7 @@
"formattedStars": "1k",
"license": "Other",
"lastRelease": "2025-09-01T03:57:54Z",
- "formattedLastRelease": "2 months ago"
+ "formattedLastRelease": "3 months ago"
},
"graphapi-io/resources": {
"hasCommitsInLast3Months": false,
@@ -57,7 +57,7 @@
},
"hasura/graphql-engine": {
"hasCommitsInLast3Months": false,
- "stars": 31827,
+ "stars": 31835,
"formattedStars": "32k",
"license": "Apache License 2.0",
"lastRelease": "2025-10-14T15:20:38Z",
@@ -65,23 +65,23 @@
},
"graphql-hive/platform": {
"hasCommitsInLast3Months": false,
- "stars": 471,
- "formattedStars": "471",
+ "stars": 472,
+ "formattedStars": "472",
"license": "MIT License",
- "lastRelease": "2025-11-25T15:15:47Z",
- "formattedLastRelease": "3 days ago"
+ "lastRelease": "2025-12-11T15:59:16Z",
+ "formattedLastRelease": "1 day ago"
},
"Kong/insomnia": {
"hasCommitsInLast3Months": false,
- "stars": 37611,
+ "stars": 37667,
"formattedStars": "38k",
"license": "Apache License 2.0",
- "lastRelease": "2025-11-21T17:29:45Z",
- "formattedLastRelease": "1 week ago"
+ "lastRelease": "2025-12-12T19:24:57Z",
+ "formattedLastRelease": "1 hour ago"
},
"postmanlabs/postman-app-support": {
"hasCommitsInLast3Months": false,
- "stars": 5979,
+ "stars": 5982,
"formattedStars": "6k",
"license": "Unknown",
"lastRelease": "",
@@ -97,87 +97,39 @@
},
"TykTechnologies/tyk": {
"hasCommitsInLast3Months": false,
- "stars": 10515,
+ "stars": 10532,
"formattedStars": "11k",
"license": "Other",
"lastRelease": "2025-11-28T16:32:34Z",
- "formattedLastRelease": "19 hours ago"
+ "formattedLastRelease": "2 weeks ago"
},
"twinlogix/typetta": {
"hasCommitsInLast3Months": false,
- "stars": 115,
- "formattedStars": "115",
+ "stars": 116,
+ "formattedStars": "116",
"license": "Apache License 2.0",
"lastRelease": "2023-10-16T07:50:50Z",
"formattedLastRelease": "2 years ago"
},
"webiny/webiny-js": {
"hasCommitsInLast3Months": false,
- "stars": 7894,
+ "stars": 7900,
"formattedStars": "8k",
"license": "Other",
- "lastRelease": "2025-09-16T08:29:00Z",
- "formattedLastRelease": "2 months ago"
+ "lastRelease": "2025-12-09T11:36:01Z",
+ "formattedLastRelease": "3 days ago"
},
"ballerina-platform/module-ballerina-graphql": {
"hasCommitsInLast3Months": false,
"stars": 138,
"formattedStars": "138",
"license": "Apache License 2.0",
- "lastRelease": "2025-11-06T10:54:08Z",
- "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": 343,
- "formattedStars": "343",
- "license": "MIT License",
- "lastRelease": "2024-12-10T17:25:31Z",
- "formattedLastRelease": "11 months ago"
- },
- "graphql/libgraphqlparser": {
- "hasCommitsInLast3Months": false,
- "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": ""
+ "lastRelease": "2025-12-08T12:39:34Z",
+ "formattedLastRelease": "4 days ago"
},
"graphql-dotnet/graphql-client": {
"hasCommitsInLast3Months": false,
- "stars": 644,
+ "stars": 645,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2024-05-21T07:06:30Z",
@@ -197,7 +149,7 @@
"formattedStars": "8",
"license": "MIT License",
"lastRelease": "2025-11-14T07:39:17Z",
- "formattedLastRelease": "2 weeks ago"
+ "formattedLastRelease": "4 weeks ago"
},
"sahb1239/SAHB.GraphQLClient": {
"hasCommitsInLast3Months": false,
@@ -217,19 +169,19 @@
},
"EntityGraphQL/EntityGraphQL": {
"hasCommitsInLast3Months": false,
- "stars": 449,
- "formattedStars": "449",
+ "stars": 450,
+ "formattedStars": "450",
"license": "MIT License",
- "lastRelease": "2025-09-16T00:35:14Z",
- "formattedLastRelease": "2 months ago"
+ "lastRelease": "2025-12-01T22:09:40Z",
+ "formattedLastRelease": "1 week ago"
},
"graphql-dotnet/graphql-dotnet": {
"hasCommitsInLast3Months": false,
- "stars": 5975,
+ "stars": 5976,
"formattedStars": "6k",
"license": "MIT License",
"lastRelease": "2025-11-17T17:57:35Z",
- "formattedLastRelease": "1 week ago"
+ "formattedLastRelease": "3 weeks ago"
},
"chkimes/graphql-net": {
"hasCommitsInLast3Months": false,
@@ -247,37 +199,37 @@
"lastRelease": "",
"formattedLastRelease": ""
},
- "burner/graphqld": {
+ "microsoft/cppgraphqlgen": {
"hasCommitsInLast3Months": false,
- "stars": 35,
- "formattedStars": "35",
- "license": "GNU Lesser General Public License v3.0",
- "lastRelease": "2024-05-14T13:42:29Z",
+ "stars": 343,
+ "formattedStars": "343",
+ "license": "MIT License",
+ "lastRelease": "2024-12-10T17:25:31Z",
"formattedLastRelease": "1 year ago"
},
- "annkissam/common_graphql_client": {
+ "graphql/libgraphqlparser": {
"hasCommitsInLast3Months": false,
- "stars": 42,
- "formattedStars": "42",
+ "stars": 1102,
+ "formattedStars": "1k",
"license": "MIT License",
- "lastRelease": "2020-05-05T16:48:50Z",
- "formattedLastRelease": "5 years ago"
+ "lastRelease": "2017-10-16T21:47:42Z",
+ "formattedLastRelease": "8 years ago"
},
- "uesteibar/neuron": {
+ "burner/graphqld": {
"hasCommitsInLast3Months": false,
- "stars": 333,
- "formattedStars": "333",
- "license": "Other",
- "lastRelease": "",
- "formattedLastRelease": ""
+ "stars": 35,
+ "formattedStars": "35",
+ "license": "GNU Lesser General Public License v3.0",
+ "lastRelease": "2024-05-14T13:42:29Z",
+ "formattedLastRelease": "1 year ago"
},
"absinthe-graphql/absinthe": {
"hasCommitsInLast3Months": false,
- "stars": 4374,
+ "stars": 4379,
"formattedStars": "4k",
"license": "Other",
"lastRelease": "2025-11-21T15:08:24Z",
- "formattedLastRelease": "1 week ago"
+ "formattedLastRelease": "3 weeks ago"
},
"graphql-elixir/graphql": {
"hasCommitsInLast3Months": false,
@@ -295,6 +247,14 @@
"lastRelease": "",
"formattedLastRelease": ""
},
+ "oliyh/re-graph": {
+ "hasCommitsInLast3Months": false,
+ "stars": 464,
+ "formattedStars": "464",
+ "license": "Unknown",
+ "lastRelease": "2022-07-20T09:24:02Z",
+ "formattedLastRelease": "3 years ago"
+ },
"jlouis/graphql-erlang": {
"hasCommitsInLast3Months": false,
"stars": 314,
@@ -303,9 +263,33 @@
"lastRelease": "2018-06-22T12:35:43Z",
"formattedLastRelease": "7 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": ""
+ },
"gql-dart/ferry": {
"hasCommitsInLast3Months": false,
- "stars": 628,
+ "stars": 630,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "",
@@ -319,9 +303,33 @@
"lastRelease": "2025-10-21T16:42:55Z",
"formattedLastRelease": "1 month ago"
},
+ "annkissam/common_graphql_client": {
+ "hasCommitsInLast3Months": false,
+ "stars": 42,
+ "formattedStars": "42",
+ "license": "MIT License",
+ "lastRelease": "2020-05-05T16:48:50Z",
+ "formattedLastRelease": "5 years ago"
+ },
+ "uesteibar/neuron": {
+ "hasCommitsInLast3Months": false,
+ "stars": 333,
+ "formattedStars": "333",
+ "license": "Other",
+ "lastRelease": "",
+ "formattedLastRelease": ""
+ },
+ "dosco/graphjin": {
+ "hasCommitsInLast3Months": false,
+ "stars": 3014,
+ "formattedStars": "3k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-11-05T07:51:12Z",
+ "formattedLastRelease": "1 month ago"
+ },
"Khan/genqlient": {
"hasCommitsInLast3Months": false,
- "stars": 1266,
+ "stars": 1274,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2025-05-18T19:09:08Z",
@@ -329,15 +337,15 @@
},
"hasura/go-graphql-client": {
"hasCommitsInLast3Months": false,
- "stars": 459,
- "formattedStars": "459",
+ "stars": 461,
+ "formattedStars": "461",
"license": "MIT License",
"lastRelease": "2025-11-05T06:45:53Z",
- "formattedLastRelease": "3 weeks ago"
+ "formattedLastRelease": "1 month ago"
},
"shurcooL/graphql": {
"hasCommitsInLast3Months": false,
- "stars": 728,
+ "stars": 727,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "",
@@ -353,11 +361,11 @@
},
"99designs/gqlgen": {
"hasCommitsInLast3Months": false,
- "stars": 10593,
+ "stars": 10607,
"formattedStars": "11k",
"license": "MIT License",
"lastRelease": "2025-11-24T16:56:20Z",
- "formattedLastRelease": "4 days ago"
+ "formattedLastRelease": "2 weeks ago"
},
"andrewwphillips/eggql": {
"hasCommitsInLast3Months": false,
@@ -377,15 +385,15 @@
},
"graph-gophers/graphql-go": {
"hasCommitsInLast3Months": false,
- "stars": 4741,
+ "stars": 4743,
"formattedStars": "5k",
"license": "BSD 2-Clause \"Simplified\" License",
"lastRelease": "2025-09-09T11:37:07Z",
- "formattedLastRelease": "2 months ago"
+ "formattedLastRelease": "3 months ago"
},
"graphql-go/graphql": {
"hasCommitsInLast3Months": false,
- "stars": 10132,
+ "stars": 10135,
"formattedStars": "10k",
"license": "MIT License",
"lastRelease": "2023-04-10T18:20:23Z",
@@ -409,43 +417,43 @@
},
"wundergraph/graphql-go-tools": {
"hasCommitsInLast3Months": false,
- "stars": 790,
+ "stars": 814,
"formattedStars": "1k",
"license": "MIT License",
- "lastRelease": "2025-11-21T21:18:20Z",
- "formattedLastRelease": "1 week ago"
+ "lastRelease": "2025-12-10T11:25:46Z",
+ "formattedLastRelease": "2 days ago"
},
- "dosco/graphjin": {
+ "morpheusgraphql/morpheus-graphql": {
"hasCommitsInLast3Months": false,
- "stars": 3011,
- "formattedStars": "3k",
- "license": "Apache License 2.0",
- "lastRelease": "2025-11-05T07:51:12Z",
- "formattedLastRelease": "3 weeks ago"
+ "stars": 418,
+ "formattedStars": "418",
+ "license": "MIT License",
+ "lastRelease": "2024-06-10T08:34:35Z",
+ "formattedLastRelease": "1 year ago"
},
- "grails/gorm-graphql": {
+ "apollographql/apollo-kotlin": {
"hasCommitsInLast3Months": false,
- "stars": 81,
- "formattedStars": "81",
- "license": "Unknown",
- "lastRelease": "2023-12-08T10:48:05Z",
- "formattedLastRelease": "1 year ago"
+ "stars": 3930,
+ "formattedStars": "4k",
+ "license": "MIT License",
+ "lastRelease": "2025-11-13T17:33:51Z",
+ "formattedLastRelease": "4 weeks ago"
},
- "grooviter/gql": {
+ "ExpediaGroup/graphql-kotlin": {
"hasCommitsInLast3Months": false,
- "stars": 49,
- "formattedStars": "49",
+ "stars": 1796,
+ "formattedStars": "2k",
"license": "Apache License 2.0",
- "lastRelease": "2024-11-05T10:13:23Z",
- "formattedLastRelease": "1 year ago"
+ "lastRelease": "2025-06-16T17:02:18Z",
+ "formattedLastRelease": "5 months ago"
},
- "morpheusgraphql/morpheus-graphql": {
+ "americanexpress/nodes": {
"hasCommitsInLast3Months": false,
- "stars": 418,
- "formattedStars": "418",
- "license": "MIT License",
- "lastRelease": "2024-06-10T08:34:35Z",
- "formattedLastRelease": "1 year ago"
+ "stars": 307,
+ "formattedStars": "307",
+ "license": "Apache License 2.0",
+ "lastRelease": "2019-07-13T22:47:01Z",
+ "formattedLastRelease": "6 years ago"
},
"jasonsychau/graphql-w-persistent": {
"hasCommitsInLast3Months": false,
@@ -463,47 +471,135 @@
"lastRelease": "2021-01-11T11:19:38Z",
"formattedLastRelease": "4 years ago"
},
- "apollographql/apollo-client": {
+ "grails/gorm-graphql": {
"hasCommitsInLast3Months": false,
- "stars": 19673,
- "formattedStars": "20k",
- "license": "MIT License",
- "lastRelease": "2025-11-19T01:20:25Z",
- "formattedLastRelease": "1 week ago"
+ "stars": 81,
+ "formattedStars": "81",
+ "license": "Unknown",
+ "lastRelease": "2023-12-08T10:48:05Z",
+ "formattedLastRelease": "2 years ago"
},
- "aws-amplify/amplify-js": {
+ "grooviter/gql": {
"hasCommitsInLast3Months": false,
- "stars": 9567,
- "formattedStars": "10k",
+ "stars": 49,
+ "formattedStars": "49",
"license": "Apache License 2.0",
- "lastRelease": "2025-11-06T13:36:19Z",
- "formattedLastRelease": "3 weeks ago"
+ "lastRelease": "2024-11-05T10:13:23Z",
+ "formattedLastRelease": "1 year ago"
},
- "Houfeng/gq-loader": {
+ "graphql-java-generator/graphql-gradle-plugin-project": {
"hasCommitsInLast3Months": false,
- "stars": 59,
- "formattedStars": "59",
- "license": "Unknown",
+ "stars": 57,
+ "formattedStars": "57",
+ "license": "MIT License",
"lastRelease": "",
"formattedLastRelease": ""
},
- "gqty-dev/gqty": {
+ "graphql-calculator/graphql-calculator": {
"hasCommitsInLast3Months": false,
- "stars": 1030,
- "formattedStars": "1k",
- "license": "MIT License",
- "lastRelease": "2025-10-26T19:29:38Z",
- "formattedLastRelease": "1 month ago"
+ "stars": 112,
+ "formattedStars": "112",
+ "license": "Apache License 2.0",
+ "lastRelease": "2021-09-03T01:56:25Z",
+ "formattedLastRelease": "4 years ago"
},
- "grafoojs/grafoo": {
+ "graphql-java-kickstart/graphql-spring-boot": {
"hasCommitsInLast3Months": false,
- "stars": 274,
- "formattedStars": "274",
+ "stars": 1513,
+ "formattedStars": "2k",
"license": "MIT License",
- "lastRelease": "2018-06-20T15:21:00Z",
- "formattedLastRelease": "7 years ago"
+ "lastRelease": "2023-12-07T11:07:47Z",
+ "formattedLastRelease": "2 years ago"
},
- "badbatch/graphql-box": {
+ "graphql-java/graphql-java": {
+ "hasCommitsInLast3Months": false,
+ "stars": 6227,
+ "formattedStars": "6k",
+ "license": "MIT License",
+ "lastRelease": "2025-11-10T01:21:35Z",
+ "formattedLastRelease": "1 month ago"
+ },
+ "babyfish-ct/jimmer": {
+ "hasCommitsInLast3Months": false,
+ "stars": 1581,
+ "formattedStars": "2k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-11-26T13:05:27Z",
+ "formattedLastRelease": "2 weeks 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": 3281,
+ "formattedStars": "3k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-12-05T21:45:25Z",
+ "formattedLastRelease": "6 days ago"
+ },
+ "spring-projects/spring-graphql": {
+ "hasCommitsInLast3Months": false,
+ "stars": 1580,
+ "formattedStars": "2k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-11-18T10:05:26Z",
+ "formattedLastRelease": "3 weeks ago"
+ },
+ "apollographql/apollo-client": {
+ "hasCommitsInLast3Months": false,
+ "stars": 19681,
+ "formattedStars": "20k",
+ "license": "MIT License",
+ "lastRelease": "2025-12-10T08:08:29Z",
+ "formattedLastRelease": "2 days ago"
+ },
+ "aws-amplify/amplify-js": {
+ "hasCommitsInLast3Months": false,
+ "stars": 9570,
+ "formattedStars": "10k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-12-10T14:00:23Z",
+ "formattedLastRelease": "2 days ago"
+ },
+ "Houfeng/gq-loader": {
+ "hasCommitsInLast3Months": false,
+ "stars": 59,
+ "formattedStars": "59",
+ "license": "Unknown",
+ "lastRelease": "",
+ "formattedLastRelease": ""
+ },
+ "gqty-dev/gqty": {
+ "hasCommitsInLast3Months": false,
+ "stars": 1031,
+ "formattedStars": "1k",
+ "license": "MIT License",
+ "lastRelease": "2025-10-26T19:29:38Z",
+ "formattedLastRelease": "1 month ago"
+ },
+ "grafoojs/grafoo": {
+ "hasCommitsInLast3Months": false,
+ "stars": 274,
+ "formattedStars": "274",
+ "license": "MIT License",
+ "lastRelease": "2018-06-20T15:21:00Z",
+ "formattedLastRelease": "7 years ago"
+ },
+ "badbatch/graphql-box": {
"hasCommitsInLast3Months": false,
"stars": 27,
"formattedStars": "27",
@@ -513,32 +609,32 @@
},
"nearform/graphql-hooks": {
"hasCommitsInLast3Months": false,
- "stars": 1889,
+ "stars": 1888,
"formattedStars": "2k",
"license": "Other",
"lastRelease": "2025-01-08T18:45:52Z",
- "formattedLastRelease": "10 months ago"
+ "formattedLastRelease": "11 months ago"
},
"graphql/graphql-http": {
"hasCommitsInLast3Months": false,
- "stars": 357,
- "formattedStars": "357",
+ "stars": 359,
+ "formattedStars": "359",
"license": "MIT License",
"lastRelease": "2025-01-17T14:16:52Z",
"formattedLastRelease": "10 months ago"
},
"jasonkuhrt/graphql-request": {
"hasCommitsInLast3Months": false,
- "stars": 6081,
+ "stars": 6086,
"formattedStars": "6k",
"license": "MIT License",
- "lastRelease": "2025-11-25T16:55:56Z",
- "formattedLastRelease": "3 days ago"
+ "lastRelease": "2025-12-12T15:51:04Z",
+ "formattedLastRelease": "4 hours ago"
},
"enisdenjo/graphql-sse": {
"hasCommitsInLast3Months": false,
- "stars": 435,
- "formattedStars": "435",
+ "stars": 438,
+ "formattedStars": "438",
"license": "MIT License",
"lastRelease": "2025-10-22T16:19:40Z",
"formattedLastRelease": "1 month ago"
@@ -553,7 +649,7 @@
},
"enisdenjo/graphql-ws": {
"hasCommitsInLast3Months": false,
- "stars": 1843,
+ "stars": 1846,
"formattedStars": "2k",
"license": "MIT License",
"lastRelease": "2025-07-14T12:15:37Z",
@@ -585,59 +681,43 @@
},
"facebook/relay": {
"hasCommitsInLast3Months": false,
- "stars": 18893,
+ "stars": 18900,
"formattedStars": "19k",
"license": "MIT License",
"lastRelease": "2025-08-06T23:45:00Z",
- "formattedLastRelease": "3 months ago"
+ "formattedLastRelease": "4 months ago"
},
"FormidableLabs/urql": {
"hasCommitsInLast3Months": false,
- "stars": 8900,
+ "stars": 8905,
"formattedStars": "9k",
"license": "MIT License",
"lastRelease": "2025-08-29T08:06:41Z",
"formattedLastRelease": "3 months ago"
},
- "apollographql/apollo-server": {
- "hasCommitsInLast3Months": false,
- "stars": 13926,
- "formattedStars": "14k",
- "license": "MIT License",
- "lastRelease": "2025-11-21T23:19:03Z",
- "formattedLastRelease": "1 week ago"
- },
- "graphql/graphql-js": {
+ "neomatrixcode/Diana.jl": {
"hasCommitsInLast3Months": false,
- "stars": 20279,
- "formattedStars": "20k",
+ "stars": 117,
+ "formattedStars": "117",
"license": "MIT License",
- "lastRelease": "2025-11-01T14:18:53Z",
- "formattedLastRelease": "3 weeks ago"
+ "lastRelease": "2022-08-16T03:22:22Z",
+ "formattedLastRelease": "3 years ago"
},
- "dotansimha/graphql-yoga": {
+ "DeloitteDigitalAPAC/GraphQLClient.jl": {
"hasCommitsInLast3Months": false,
- "stars": 8455,
- "formattedStars": "8k",
- "license": "MIT License",
- "lastRelease": "2025-11-28T11:05:21Z",
- "formattedLastRelease": "1 day ago"
+ "stars": 47,
+ "formattedStars": "47",
+ "license": "Other",
+ "lastRelease": "2022-10-26T16:48:16Z",
+ "formattedLastRelease": "3 years ago"
},
- "mercurius-js/mercurius": {
+ "andreas/ocaml-graphql-server": {
"hasCommitsInLast3Months": false,
- "stars": 2462,
- "formattedStars": "2k",
+ "stars": 621,
+ "formattedStars": "1k",
"license": "MIT License",
- "lastRelease": "2025-11-13T14:12:18Z",
- "formattedLastRelease": "2 weeks ago"
- },
- "getcronit/pylon": {
- "hasCommitsInLast3Months": false,
- "stars": 345,
- "formattedStars": "345",
- "license": "Apache License 2.0",
- "lastRelease": "2025-10-01T08:35:15Z",
- "formattedLastRelease": "1 month ago"
+ "lastRelease": "2022-07-08T16:26:45Z",
+ "formattedLastRelease": "3 years ago"
},
"networkimprov/brangr": {
"hasCommitsInLast3Months": false,
@@ -649,19 +729,19 @@
},
"hayes/giraphql": {
"hasCommitsInLast3Months": false,
- "stars": 2553,
+ "stars": 2561,
"formattedStars": "3k",
"license": "ISC License",
- "lastRelease": "2025-11-10T01:29:18Z",
- "formattedLastRelease": "2 weeks ago"
+ "lastRelease": "2025-12-10T22:07:12Z",
+ "formattedLastRelease": "1 day ago"
},
"graphql/graphiql": {
"hasCommitsInLast3Months": false,
- "stars": 16715,
+ "stars": 16730,
"formattedStars": "17k",
"license": "MIT License",
- "lastRelease": "2025-11-01T22:30:04Z",
- "formattedLastRelease": "3 weeks ago"
+ "lastRelease": "2025-11-30T09:04:01Z",
+ "formattedLastRelease": "1 week ago"
},
"Urigo/graphql-cli": {
"hasCommitsInLast3Months": false,
@@ -673,11 +753,11 @@
},
"dotansimha/graphql-code-generator": {
"hasCommitsInLast3Months": false,
- "stars": 11179,
+ "stars": 11183,
"formattedStars": "11k",
"license": "MIT License",
"lastRelease": "2025-11-29T04:07:19Z",
- "formattedLastRelease": "7 hours ago"
+ "formattedLastRelease": "1 week ago"
},
"kamilkisiela/graphql-config": {
"hasCommitsInLast3Months": false,
@@ -689,7 +769,7 @@
},
"dimaMachina/graphql-eslint/": {
"hasCommitsInLast3Months": false,
- "stars": 831,
+ "stars": 832,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2025-03-26T14:11:23Z",
@@ -700,8 +780,8 @@
"stars": 1725,
"formattedStars": "2k",
"license": "MIT License",
- "lastRelease": "2025-11-15T02:42:13Z",
- "formattedLastRelease": "2 weeks ago"
+ "lastRelease": "2025-12-10T22:16:19Z",
+ "formattedLastRelease": "1 day ago"
},
"graphql/graphql-language-service": {
"hasCommitsInLast3Months": false,
@@ -713,18 +793,18 @@
},
"n1ru4l/graphql-live-query": {
"hasCommitsInLast3Months": false,
- "stars": 440,
- "formattedStars": "440",
+ "stars": 441,
+ "formattedStars": "441",
"license": "MIT License",
"lastRelease": "2022-07-29T09:27:53Z",
"formattedLastRelease": "3 years ago"
},
"Urigo/graphql-mesh": {
"hasCommitsInLast3Months": false,
- "stars": 3463,
+ "stars": 3465,
"formattedStars": "3k",
"license": "MIT License",
- "lastRelease": "2025-11-19T12:12:00Z",
+ "lastRelease": "2025-12-04T22:32:32Z",
"formattedLastRelease": "1 week ago"
},
"maticzav/graphql-middleware": {
@@ -745,7 +825,7 @@
},
"Urigo/graphql-scalars": {
"hasCommitsInLast3Months": false,
- "stars": 1927,
+ "stars": 1929,
"formattedStars": "2k",
"license": "MIT License",
"lastRelease": "2025-10-14T23:00:24Z",
@@ -753,7 +833,7 @@
},
"maticzav/graphql-shield": {
"hasCommitsInLast3Months": false,
- "stars": 3574,
+ "stars": 3573,
"formattedStars": "4k",
"license": "MIT License",
"lastRelease": "2022-11-22T19:08:37Z",
@@ -761,11 +841,11 @@
},
"ardatan/graphql-tools": {
"hasCommitsInLast3Months": false,
- "stars": 5418,
+ "stars": 5416,
"formattedStars": "5k",
"license": "MIT License",
"lastRelease": "2025-11-28T10:05:14Z",
- "formattedLastRelease": "1 day ago"
+ "formattedLastRelease": "2 weeks ago"
},
"anvilco/graphql-introspection-tools": {
"hasCommitsInLast3Months": false,
@@ -777,7 +857,7 @@
},
"graphile/postgraphile": {
"hasCommitsInLast3Months": false,
- "stars": 12858,
+ "stars": 12866,
"formattedStars": "13k",
"license": "Other",
"lastRelease": "2023-10-05T16:27:00Z",
@@ -785,7 +865,7 @@
},
"Urigo/SOFA": {
"hasCommitsInLast3Months": false,
- "stars": 1111,
+ "stars": 1112,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2024-12-16T10:06:41Z",
@@ -793,59 +873,131 @@
},
"anvilco/spectaql": {
"hasCommitsInLast3Months": false,
- "stars": 1205,
+ "stars": 1207,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "",
"formattedLastRelease": ""
},
- "neomatrixcode/Diana.jl": {
+ "apollographql/apollo-server": {
"hasCommitsInLast3Months": false,
- "stars": 117,
- "formattedStars": "117",
+ "stars": 13930,
+ "formattedStars": "14k",
"license": "MIT License",
- "lastRelease": "2022-08-16T03:22:22Z",
- "formattedLastRelease": "3 years ago"
+ "lastRelease": "2025-11-21T23:19:03Z",
+ "formattedLastRelease": "2 weeks ago"
},
- "DeloitteDigitalAPAC/GraphQLClient.jl": {
+ "graphql/graphql-js": {
"hasCommitsInLast3Months": false,
- "stars": 47,
- "formattedStars": "47",
- "license": "Other",
- "lastRelease": "2022-10-26T16:48:16Z",
- "formattedLastRelease": "3 years ago"
+ "stars": 20290,
+ "formattedStars": "20k",
+ "license": "MIT License",
+ "lastRelease": "2025-11-01T14:18:53Z",
+ "formattedLastRelease": "1 month ago"
},
- "andreas/ocaml-graphql-server": {
+ "dotansimha/graphql-yoga": {
"hasCommitsInLast3Months": false,
- "stars": 621,
- "formattedStars": "1k",
+ "stars": 8460,
+ "formattedStars": "8k",
"license": "MIT License",
- "lastRelease": "2022-07-08T16:26:45Z",
- "formattedLastRelease": "3 years ago"
+ "lastRelease": "2025-12-02T00:13:11Z",
+ "formattedLastRelease": "1 week ago"
+ },
+ "mercurius-js/mercurius": {
+ "hasCommitsInLast3Months": false,
+ "stars": 2464,
+ "formattedStars": "2k",
+ "license": "MIT License",
+ "lastRelease": "2025-11-13T14:12:18Z",
+ "formattedLastRelease": "4 weeks ago"
+ },
+ "getcronit/pylon": {
+ "hasCommitsInLast3Months": false,
+ "stars": 348,
+ "formattedStars": "348",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-10-01T08:35:15Z",
+ "formattedLastRelease": "2 months ago"
},
"graphql-perl/graphql-perl": {
"hasCommitsInLast3Months": false,
- "stars": 73,
- "formattedStars": "73",
+ "stars": 72,
+ "formattedStars": "72",
+ "license": "Unknown",
+ "lastRelease": "",
+ "formattedLastRelease": ""
+ },
+ "mirumee/ariadne-codegen": {
+ "hasCommitsInLast3Months": false,
+ "stars": 373,
+ "formattedStars": "373",
+ "license": "BSD 3-Clause \"New\" or \"Revised\" License",
+ "lastRelease": "2025-12-06T19:39:02Z",
+ "formattedLastRelease": "6 days ago"
+ },
+ "graphql-python/gql": {
+ "hasCommitsInLast3Months": false,
+ "stars": 1654,
+ "formattedStars": "2k",
+ "license": "MIT License",
+ "lastRelease": "2025-09-05T14:22:54Z",
+ "formattedLastRelease": "3 months ago"
+ },
+ "denisart/graphql-query": {
+ "hasCommitsInLast3Months": false,
+ "stars": 66,
+ "formattedStars": "66",
+ "license": "MIT License",
+ "lastRelease": "2024-07-31T10:54:53Z",
+ "formattedLastRelease": "1 year ago"
+ },
+ "prisma-labs/python-graphql-client": {
+ "hasCommitsInLast3Months": false,
+ "stars": 156,
+ "formattedStars": "156",
+ "license": "MIT License",
+ "lastRelease": "",
+ "formattedLastRelease": ""
+ },
+ "dsal3389/ql": {
+ "hasCommitsInLast3Months": false,
+ "stars": 9,
+ "formattedStars": "9",
"license": "Unknown",
+ "lastRelease": "2025-02-04T17:36:51Z",
+ "formattedLastRelease": "10 months ago"
+ },
+ "qlient-org/python-qlient": {
+ "hasCommitsInLast3Months": false,
+ "stars": 46,
+ "formattedStars": "46",
+ "license": "MIT License",
+ "lastRelease": "2022-07-29T16:10:08Z",
+ "formattedLastRelease": "3 years ago"
+ },
+ "profusion/sgqlc": {
+ "hasCommitsInLast3Months": false,
+ "stars": 547,
+ "formattedStars": "1k",
+ "license": "ISC License",
"lastRelease": "",
"formattedLastRelease": ""
},
"api-platform/api-platform": {
"hasCommitsInLast3Months": false,
- "stars": 9054,
+ "stars": 9066,
"formattedStars": "9k",
"license": "MIT License",
"lastRelease": "2025-03-11T16:15:41Z",
- "formattedLastRelease": "8 months ago"
+ "formattedLastRelease": "9 months ago"
},
"GatoGraphQL/GatoGraphQL": {
"hasCommitsInLast3Months": false,
- "stars": 376,
- "formattedStars": "376",
+ "stars": 377,
+ "formattedStars": "377",
"license": "GNU General Public License v2.0",
"lastRelease": "2025-11-26T08:29:30Z",
- "formattedLastRelease": "3 days ago"
+ "formattedLastRelease": "2 weeks ago"
},
"infinityloop-dev/graphpinator": {
"hasCommitsInLast3Months": false,
@@ -861,15 +1013,15 @@
"formattedStars": "16",
"license": "MIT License",
"lastRelease": "2025-10-11T09:19:14Z",
- "formattedLastRelease": "1 month ago"
+ "formattedLastRelease": "2 months ago"
},
"webonyx/graphql-php": {
"hasCommitsInLast3Months": false,
- "stars": 4702,
+ "stars": 4706,
"formattedStars": "5k",
"license": "MIT License",
- "lastRelease": "2025-11-20T11:51:16Z",
- "formattedLastRelease": "1 week ago"
+ "lastRelease": "2025-12-09T07:31:19Z",
+ "formattedLastRelease": "3 days ago"
},
"ivome/graphql-relay-php": {
"hasCommitsInLast3Months": false,
@@ -885,7 +1037,7 @@
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2025-10-31T08:00:22Z",
- "formattedLastRelease": "4 weeks ago"
+ "formattedLastRelease": "1 month ago"
},
"thecodingmachine/graphqlite": {
"hasCommitsInLast3Months": false,
@@ -893,15 +1045,15 @@
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2025-09-04T16:39:26Z",
- "formattedLastRelease": "2 months ago"
+ "formattedLastRelease": "3 months ago"
},
"nuwave/lighthouse": {
"hasCommitsInLast3Months": false,
- "stars": 3465,
+ "stars": 3471,
"formattedStars": "3k",
"license": "MIT License",
- "lastRelease": "2025-09-11T08:07:50Z",
- "formattedLastRelease": "2 months ago"
+ "lastRelease": "2025-12-05T08:19:37Z",
+ "formattedLastRelease": "1 week ago"
},
"railt/railt": {
"hasCommitsInLast3Months": false,
@@ -929,71 +1081,63 @@
},
"wp-graphql/wp-graphql": {
"hasCommitsInLast3Months": false,
- "stars": 3759,
+ "stars": 3758,
"formattedStars": "4k",
"license": "GNU General Public License v3.0",
"lastRelease": "2025-11-24T22:39:55Z",
- "formattedLastRelease": "4 days ago"
+ "formattedLastRelease": "2 weeks ago"
},
- "mirumee/ariadne-codegen": {
+ "ropensci/ghql": {
"hasCommitsInLast3Months": false,
- "stars": 368,
- "formattedStars": "368",
- "license": "BSD 3-Clause \"New\" or \"Revised\" License",
- "lastRelease": "2025-10-13T06:38:02Z",
- "formattedLastRelease": "1 month ago"
+ "stars": 149,
+ "formattedStars": "149",
+ "license": "Other",
+ "lastRelease": "2025-09-08T08:41:00Z",
+ "formattedLastRelease": "3 months ago"
},
- "graphql-python/gql": {
+ "ghostdogpr/caliban": {
"hasCommitsInLast3Months": false,
- "stars": 1653,
- "formattedStars": "2k",
- "license": "MIT License",
- "lastRelease": "2025-09-05T14:22:54Z",
- "formattedLastRelease": "2 months ago"
+ "stars": 977,
+ "formattedStars": "1k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-07-14T00:24:20Z",
+ "formattedLastRelease": "4 months ago"
},
- "denisart/graphql-query": {
+ "ohler55/agoo": {
"hasCommitsInLast3Months": false,
- "stars": 66,
- "formattedStars": "66",
+ "stars": 924,
+ "formattedStars": "1k",
"license": "MIT License",
- "lastRelease": "2024-07-31T10:54:53Z",
- "formattedLastRelease": "1 year ago"
+ "lastRelease": "2025-09-24T22:20:23Z",
+ "formattedLastRelease": "2 months ago"
},
- "prisma-labs/python-graphql-client": {
+ "rmosolgo/graphql-ruby": {
"hasCommitsInLast3Months": false,
- "stars": 156,
- "formattedStars": "156",
+ "stars": 5427,
+ "formattedStars": "5k",
"license": "MIT License",
- "lastRelease": "",
- "formattedLastRelease": ""
- },
- "dsal3389/ql": {
- "hasCommitsInLast3Months": false,
- "stars": 9,
- "formattedStars": "9",
- "license": "Unknown",
- "lastRelease": "2025-02-04T17:36:51Z",
- "formattedLastRelease": "9 months ago"
+ "lastRelease": "2025-07-19T17:15:49Z",
+ "formattedLastRelease": "4 months ago"
},
- "qlient-org/python-qlient": {
+ "virtualshield/rails-graphql": {
"hasCommitsInLast3Months": false,
- "stars": 46,
- "formattedStars": "46",
+ "stars": 187,
+ "formattedStars": "187",
"license": "MIT License",
- "lastRelease": "2022-07-29T16:10:08Z",
- "formattedLastRelease": "3 years ago"
+ "lastRelease": "2025-08-25T17:53:38Z",
+ "formattedLastRelease": "3 months ago"
},
- "profusion/sgqlc": {
+ "sangria-graphql/sangria": {
"hasCommitsInLast3Months": false,
- "stars": 546,
- "formattedStars": "1k",
- "license": "ISC License",
- "lastRelease": "",
- "formattedLastRelease": ""
+ "stars": 1957,
+ "formattedStars": "2k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-10-20T11:40:30Z",
+ "formattedLastRelease": "1 month ago"
},
"mirumee/ariadne": {
"hasCommitsInLast3Months": false,
- "stars": 2309,
+ "stars": 2310,
"formattedStars": "2k",
"license": "BSD 3-Clause \"New\" or \"Revised\" License",
"lastRelease": "2025-04-18T08:27:47Z",
@@ -1017,7 +1161,7 @@
},
"graphql-python/graphene": {
"hasCommitsInLast3Months": false,
- "stars": 8239,
+ "stars": 8240,
"formattedStars": "8k",
"license": "MIT License",
"lastRelease": "2024-11-09T20:43:58Z",
@@ -1025,203 +1169,131 @@
},
"strawberry-graphql/strawberry": {
"hasCommitsInLast3Months": false,
- "stars": 4569,
+ "stars": 4571,
"formattedStars": "5k",
"license": "MIT License",
- "lastRelease": "2025-11-22T13:00:06Z",
- "formattedLastRelease": "6 days ago"
+ "lastRelease": "2025-12-12T11:49:36Z",
+ "formattedLastRelease": "9 hours ago"
},
"tartiflette/tartiflette": {
"hasCommitsInLast3Months": false,
- "stars": 856,
+ "stars": 854,
"formattedStars": "1k",
"license": "MIT License",
"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": {
+ "obmarg/cynic": {
"hasCommitsInLast3Months": false,
- "stars": 1565,
- "formattedStars": "2k",
- "license": "Apache License 2.0",
- "lastRelease": "2025-11-26T13:05:27Z",
- "formattedLastRelease": "2 days ago"
+ "stars": 443,
+ "formattedStars": "443",
+ "license": "Mozilla Public License 2.0",
+ "lastRelease": "2025-08-19T19:37:22Z",
+ "formattedLastRelease": "3 months ago"
},
- "aPureBase/KGraphQL": {
+ "arthurkhlghatyan/gql-client-rs": {
"hasCommitsInLast3Months": false,
- "stars": 308,
- "formattedStars": "308",
+ "stars": 51,
+ "formattedStars": "51",
"license": "MIT License",
- "lastRelease": "2023-01-27T10:09:55Z",
- "formattedLastRelease": "2 years ago"
+ "lastRelease": "2025-06-07T14:31:10Z",
+ "formattedLastRelease": "6 months ago"
},
- "eclipse/microprofile-graphql": {
+ "async-graphql/async-graphql": {
"hasCommitsInLast3Months": false,
- "stars": 101,
- "formattedStars": "101",
+ "stars": 3606,
+ "formattedStars": "4k",
"license": "Apache License 2.0",
- "lastRelease": "2022-03-21T18:26:51Z",
- "formattedLastRelease": "3 years ago"
+ "lastRelease": "",
+ "formattedLastRelease": ""
},
- "netflix/dgs-framework": {
+ "graphql-rust/juniper": {
"hasCommitsInLast3Months": false,
- "stars": 3280,
- "formattedStars": "3k",
- "license": "Apache License 2.0",
- "lastRelease": "2025-11-24T21:04:55Z",
- "formattedLastRelease": "4 days ago"
+ "stars": 5920,
+ "formattedStars": "6k",
+ "license": "Other",
+ "lastRelease": "2025-09-08T23:23:40Z",
+ "formattedLastRelease": "3 months ago"
},
- "spring-projects/spring-graphql": {
+ "apollographql/router": {
"hasCommitsInLast3Months": false,
- "stars": 1578,
- "formattedStars": "2k",
- "license": "Apache License 2.0",
- "lastRelease": "2025-11-18T10:05:26Z",
- "formattedLastRelease": "1 week ago"
+ "stars": 941,
+ "formattedStars": "1k",
+ "license": "Other",
+ "lastRelease": "2025-12-12T12:42:12Z",
+ "formattedLastRelease": "8 hours ago"
},
- "graphql-java-generator/graphql-gradle-plugin-project": {
+ "eerimoq/gqt": {
"hasCommitsInLast3Months": false,
- "stars": 57,
- "formattedStars": "57",
+ "stars": 470,
+ "formattedStars": "470",
"license": "MIT License",
"lastRelease": "",
"formattedLastRelease": ""
},
- "ropensci/ghql": {
- "hasCommitsInLast3Months": false,
- "stars": 149,
- "formattedStars": "149",
- "license": "Other",
- "lastRelease": "2025-09-08T08:41:00Z",
- "formattedLastRelease": "2 months ago"
- },
- "ohler55/agoo": {
+ "Escape-Technologies/graphql-armor": {
"hasCommitsInLast3Months": false,
- "stars": 924,
+ "stars": 561,
"formattedStars": "1k",
"license": "MIT License",
- "lastRelease": "2025-09-24T22:20:23Z",
- "formattedLastRelease": "2 months ago"
+ "lastRelease": "2025-08-22T13:32:40Z",
+ "formattedLastRelease": "3 months ago"
},
- "rmosolgo/graphql-ruby": {
+ "ldebruijn/graphql-protect": {
"hasCommitsInLast3Months": false,
- "stars": 5428,
- "formattedStars": "5k",
+ "stars": 34,
+ "formattedStars": "34",
"license": "MIT License",
- "lastRelease": "2025-07-19T17:15:49Z",
- "formattedLastRelease": "4 months ago"
+ "lastRelease": "2025-11-25T14:27:46Z",
+ "formattedLastRelease": "2 weeks ago"
},
- "virtualshield/rails-graphql": {
+ "graphql-hive/gateway": {
"hasCommitsInLast3Months": false,
- "stars": 187,
- "formattedStars": "187",
+ "stars": 69,
+ "formattedStars": "69",
"license": "MIT License",
- "lastRelease": "2025-08-25T17:53:38Z",
- "formattedLastRelease": "3 months ago"
+ "lastRelease": "2025-12-10T19:27:44Z",
+ "formattedLastRelease": "2 days ago"
},
- "obmarg/cynic": {
+ "microcks/microcks": {
"hasCommitsInLast3Months": false,
- "stars": 442,
- "formattedStars": "442",
- "license": "Mozilla Public License 2.0",
- "lastRelease": "2025-08-19T19:37:22Z",
- "formattedLastRelease": "3 months ago"
+ "stars": 1762,
+ "formattedStars": "2k",
+ "license": "Apache License 2.0",
+ "lastRelease": "2025-12-08T15:51:55Z",
+ "formattedLastRelease": "4 days ago"
},
- "arthurkhlghatyan/gql-client-rs": {
+ "schemathesis/schemathesis": {
"hasCommitsInLast3Months": false,
- "stars": 51,
- "formattedStars": "51",
+ "stars": 2891,
+ "formattedStars": "3k",
"license": "MIT License",
- "lastRelease": "2025-06-07T14:31:10Z",
- "formattedLastRelease": "5 months ago"
+ "lastRelease": "2025-12-10T19:22:47Z",
+ "formattedLastRelease": "2 days ago"
},
- "async-graphql/async-graphql": {
+ "glideapps/quicktype": {
"hasCommitsInLast3Months": false,
- "stars": 3594,
- "formattedStars": "4k",
+ "stars": 13505,
+ "formattedStars": "14k",
"license": "Apache License 2.0",
"lastRelease": "",
"formattedLastRelease": ""
},
- "graphql-rust/juniper": {
- "hasCommitsInLast3Months": false,
- "stars": 5911,
- "formattedStars": "6k",
- "license": "Other",
- "lastRelease": "2025-09-08T23:23:40Z",
- "formattedLastRelease": "2 months ago"
- },
- "ghostdogpr/caliban": {
+ "wundergraph/cosmo": {
"hasCommitsInLast3Months": false,
- "stars": 976,
+ "stars": 1126,
"formattedStars": "1k",
"license": "Apache License 2.0",
- "lastRelease": "2025-07-14T00:24:20Z",
- "formattedLastRelease": "4 months ago"
- },
- "sangria-graphql/sangria": {
- "hasCommitsInLast3Months": false,
- "stars": 1957,
- "formattedStars": "2k",
- "license": "Apache License 2.0",
- "lastRelease": "2025-10-20T11:40:30Z",
- "formattedLastRelease": "1 month ago"
+ "lastRelease": "2025-12-10T12:36:49Z",
+ "formattedLastRelease": "2 days ago"
},
"apollographql/apollo-ios": {
"hasCommitsInLast3Months": false,
- "stars": 4011,
+ "stars": 4018,
"formattedStars": "4k",
"license": "MIT License",
- "lastRelease": "2025-11-05T23:30:57Z",
- "formattedLastRelease": "3 weeks ago"
+ "lastRelease": "2025-12-03T20:34:39Z",
+ "formattedLastRelease": "1 week ago"
},
"nerdsupremacist/Graphaello": {
"hasCommitsInLast3Months": false,
@@ -1249,7 +1321,7 @@
},
"GraphQLSwift/Graphiti": {
"hasCommitsInLast3Months": false,
- "stars": 553,
+ "stars": 554,
"formattedStars": "1k",
"license": "MIT License",
"lastRelease": "2025-08-21T19:30:20Z",
@@ -1262,77 +1334,5 @@
"license": "MIT License",
"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": 1120,
- "formattedStars": "1k",
- "license": "Apache License 2.0",
- "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 817c2fe4de..5d68e2023c 100644
--- a/scripts/get-github-info/last-success.isodate
+++ b/scripts/get-github-info/last-success.isodate
@@ -1 +1 @@
-2025-11-29T12:04:08.519Z
\ No newline at end of file
+2025-12-12T20:51:22.323Z
\ No newline at end of file
diff --git a/scripts/sync-working-groups/package.json b/scripts/sync-working-groups/package.json
index b470821c56..7659901d21 100644
--- a/scripts/sync-working-groups/package.json
+++ b/scripts/sync-working-groups/package.json
@@ -7,6 +7,6 @@
"start": "node ./sync-working-groups.ts"
},
"dependencies": {
- "arktype": "^2.1.27"
+ "arktype": "2.1.28"
}
}
diff --git a/scripts/sync-working-groups/working-group-events.ndjson b/scripts/sync-working-groups/working-group-events.ndjson
index 012d82306e..962f16860f 100644
--- a/scripts/sync-working-groups/working-group-events.ndjson
+++ b/scripts/sync-working-groups/working-group-events.ndjson
@@ -30,8 +30,12 @@
{"kind":"calendar#event","etag":"\"3524923696926750\"","id":"56uko3hh68be4q73tttdicg7l2_20251225T183000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=NTZ1a28zaGg2OGJlNHE3M3R0dGRpY2c3bDJfMjAyNTEyMjVUMTgzMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2025-10-16T15:10:58.000Z","updated":"2025-11-06T20:44:08.463Z","summary":"GraphQL AI Working Group","description":"Sign up and view agenda at https://github.com/graphql/ai-wg Zoom password: aiwg","location":"https://zoom.us/j/92302442188","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2025-12-11T13:30:00-05:00","end":"2025-12-11T14:30:00-05:00","recurringEventId":"56uko3hh68be4q73tttdicg7l2","originalStartTime":{"dateTime":"2025-12-25T13:30:00-05:00","timeZone":"America/New_York"},"transparency":"transparent","iCalUID":"56uko3hh68be4q73tttdicg7l2@google.com","sequence":1,"eventType":"default"}
{"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":"\"3529763944050462\"","id":"2ffd8o32sh77kd3mtccrtg887n_20251218T183000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=MmZmZDhvMzJzaDc3a2QzbXRjY3J0Zzg4N25fMjAyNTEyMThUMTgzMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2025-05-01T19:23:48.000Z","updated":"2025-12-04T20:59:32.025Z","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"}
+{"kind":"calendar#event","etag":"\"3530925154728702\"","id":"f7cvs5ala9jtt147l3mik2mlvl_20260105T160000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=ZjdjdnM1YWxhOWp0dDE0N2wzbWlrMm1sdmxfMjAyNjAxMDVUMTYwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2024-01-29T15:14:17.000Z","updated":"2025-12-11T14:16:17.364Z","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":"2026-01-05T11:00:00-05:00","end":"2026-01-05T12:00:00-05:00","recurringEventId":"f7cvs5ala9jtt147l3mik2mlvl","originalStartTime":{"dateTime":"2026-01-05T11:00:00-05:00","timeZone":"America/New_York"},"iCalUID":"f7cvs5ala9jtt147l3mik2mlvl@google.com","sequence":2,"guestsCanInviteOthers":false,"eventType":"default"}
+{"kind":"calendar#event","etag":"\"3526826931784574\"","id":"q3qul35gpekign7gc8cvr6bap1_20260108T140000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=cTNxdWwzNWdwZWtpZ243Z2M4Y3ZyNmJhcDFfMjAyNjAxMDhUMTQwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2023-12-08T21:20:13.000Z","updated":"2025-11-17T21:04:25.892Z","summary":"Marketing & Content Subcommittee Meeting","location":"https://zoom-lfx.platform.linuxfoundation.org/meeting/91228653788?password=0745533d-9a7a-42bb-8c72-3b823f679384","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2026-01-08T09:00:00-05:00","end":"2026-01-08T10:00:00-05:00","recurringEventId":"q3qul35gpekign7gc8cvr6bap1_R20251030T130000","originalStartTime":{"dateTime":"2026-01-08T09:00:00-05:00","timeZone":"America/New_York"},"iCalUID":"q3qul35gpekign7gc8cvr6bap1_R20251030T130000@google.com","sequence":1,"eventType":"default"}
+{"kind":"calendar#event","etag":"\"3512629578532638\"","id":"1ae8m39lvqtigc4ao1p670g8il_20260108T160000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=MWFlOG0zOWx2cXRpZ2M0YW8xcDY3MGc4aWxfMjAyNjAxMDhUMTYwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2025-02-04T14:14:16.000Z","updated":"2025-08-27T17:13:09.266Z","summary":"GraphQL Community WG","description":"Meeting password: communityhttps://github.com/graphql/community-wg/tree/main/agendas Please be aware that meetings are recorded and/or live-streamed.","location":"https://zoom.us/j/93104287544","creator":{"email":"benjie@graphile.com"},"organizer":{"email":"linuxfoundation.org_ik79t9uuj2p32i3r203dgv5mo8@group.calendar.google.com","displayName":"GraphQL Foundation - Public","self":true},"start":"2026-01-08T11:00:00-05:00","end":"2026-01-08T12:00:00-05:00","recurringEventId":"1ae8m39lvqtigc4ao1p670g8il_R20250313T150000","originalStartTime":{"dateTime":"2026-01-08T11:00:00-05:00","timeZone":"America/Los_Angeles"},"iCalUID":"1ae8m39lvqtigc4ao1p670g8il_R20250313T150000@google.com","sequence":1,"eventType":"default"}
+{"kind":"calendar#event","etag":"\"3462003293658000\"","id":"lvqspfdh491rrdmvl7k1mruqd8_20260108T170000Z","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=bHZxc3BmZGg0OTFycmRtdmw3azFtcnVxZDhfMjAyNjAxMDhUMTcwMDAwWiBsaW51eGZvdW5kYXRpb24ub3JnX2lrNzl0OXV1ajJwMzJpM3IyMDNkZ3Y1bW84QGc","created":"2024-01-12T09:56:35.000Z","updated":"2024-11-07T17:47:26.829Z","summary":"Composite schemas WG - Weekly 2","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":"2026-01-08T12:00:00-05:00","end":"2026-01-08T13:00:00-05:00","recurringEventId":"lvqspfdh491rrdmvl7k1mruqd8","originalStartTime":{"dateTime":"2026-01-08T12:00:00-05:00","timeZone":"Europe/Berlin"},"iCalUID":"lvqspfdh491rrdmvl7k1mruqd8@google.com","sequence":1,"eventType":"default"}
diff --git a/src/_design-system/breadcrumbs.tsx b/src/_design-system/breadcrumbs.tsx
index 4b42a7554a..a394874b38 100644
--- a/src/_design-system/breadcrumbs.tsx
+++ b/src/_design-system/breadcrumbs.tsx
@@ -26,9 +26,10 @@ export const Breadcrumbs = ({
const title = extractStringsFromReactNode(item.title)
const className = clsx(
- "text-neu-700 dark:text-neu-400 min-w-6 last:text-neu-800 dark:last:text-neu-800 leading-none",
+ "text-neu-700 dark:text-neu-400 min-w-6 last:text-neu-800 dark:last:text-neu-800 leading-none whitespace-pre",
href &&
"gql-focus-visible ring-inset hover:text-neu-900 hover:underline underline-offset-2",
+ item.title.length > 8 ? "overflow-hidden truncate" : "shrink-0",
)
return (
diff --git a/src/app/(development)/resources/internal/page.tsx b/src/app/(development)/resources/internal/page.tsx
new file mode 100644
index 0000000000..056959d244
--- /dev/null
+++ b/src/app/(development)/resources/internal/page.tsx
@@ -0,0 +1,8 @@
+import { readResources } from "@/resources/data"
+import { ResourcesTable } from "./resources-table"
+
+export default async function InternalResourcesPage() {
+ const resources = await readResources()
+
+ return
+}
diff --git a/src/app/(development)/resources/internal/resources-table.tsx b/src/app/(development)/resources/internal/resources-table.tsx
new file mode 100644
index 0000000000..52f667cb4d
--- /dev/null
+++ b/src/app/(development)/resources/internal/resources-table.tsx
@@ -0,0 +1,185 @@
+"use client"
+
+import SearchIcon from "@/app/conf/_design-system/pixelarticons/search.svg?svgr"
+import type { ResourceMetadata } from "@/resources/types"
+import clsx from "clsx"
+import { useState, useTransition } from "react"
+
+function fuzzyMatch(text: string, query: string): boolean {
+ const lowerText = text.toLowerCase()
+ const lowerQuery = query.toLowerCase()
+ let queryIndex = 0
+ for (let i = 0; i < lowerText.length && queryIndex < lowerQuery.length; i++) {
+ if (lowerText[i] === lowerQuery[queryIndex]) {
+ queryIndex++
+ }
+ }
+ return queryIndex === lowerQuery.length
+}
+
+function matchesSearch(resource: ResourceMetadata, query: string): boolean {
+ if (!query) return true
+ const searchable = [
+ resource.title,
+ resource.url,
+ resource.author,
+ resource.kind,
+ resource.description,
+ ...resource.tags,
+ ].join(" ")
+ return fuzzyMatch(searchable, query)
+}
+
+type TooltipState = {
+ content: string
+ x: number
+ y: number
+} | null
+
+type CellProps = {
+ children: string | undefined
+ onMouseMove: (e: React.MouseEvent, content: string) => void
+ onMouseLeave: () => void
+}
+
+function Cell({ children, onMouseMove, onMouseLeave }: CellProps) {
+ if (!children) return
+ return (
+ onMouseMove(e, children)}
+ onMouseLeave={onMouseLeave}
+ >
+ {children}
+
+ )
+}
+
+type ResourcesTableProps = {
+ resources: ResourceMetadata[]
+}
+
+export function ResourcesTable({ resources }: ResourcesTableProps) {
+ const [search, setSearch] = useState("")
+ const [query, setQuery] = useState("")
+ const [isPending, startTransition] = useTransition()
+ const [tooltip, setTooltip] = useState(null)
+ const [copiedIndex, setCopiedIndex] = useState(null)
+
+ const filtered = resources.filter(r => matchesSearch(r, query))
+
+ const handleMouseMove = (e: React.MouseEvent, content: string) => {
+ setTooltip({ content, x: e.clientX, y: e.clientY })
+ }
+
+ const handleMouseLeave = () => {
+ setTooltip(null)
+ }
+
+ const handleRowClick = async (resource: ResourceMetadata, index: number) => {
+ const json = JSON.stringify(resource, null, 2)
+ await navigator.clipboard.writeText(json)
+ setCopiedIndex(index)
+ setTimeout(() => setCopiedIndex(null), 1500)
+ }
+
+ return (
+
+
+
+ {
+ setSearch(e.target.value)
+ startTransition(() => setQuery(e.target.value))
+ }}
+ className="w-full bg-transparent font-mono text-sm placeholder:text-neu-600 focus:outline-none dark:placeholder:text-neu-400"
+ />
+
+
+
+
+ Title
+ URL
+ Author
+ Kind
+
+ Description
+
+ Duration
+ Tags
+
+
+
+ {filtered.map((resource, i) => (
+ handleRowClick(resource, i)}
+ >
+ |
+ {resource.title}
+ |
+
+ {resource.url}
+ |
+
+ {resource.author}
+ |
+
+ {resource.kind}
+ |
+
+ {resource.description}
+ |
+
+ {resource.duration}
+ |
+
+ {resource.tags.join(", ")}
+ |
+
+ ))}
+
+
+ {tooltip && (
+
+ {tooltip.content}
+
+ )}
+
+ )
+}
diff --git a/src/app/(main)/community/events/page.tsx b/src/app/(main)/community/events/page.tsx
index efd83a1580..cf8ee46fcd 100644
--- a/src/app/(main)/community/events/page.tsx
+++ b/src/app/(main)/community/events/page.tsx
@@ -140,7 +140,7 @@ function Stripes() {
+
+
+
Blog posts
+
{title}
+
+ {description}
+
+
+
+ {readAllLabel}
+
+
+
+
+ {posts.map(post => (
+
+ ))}
+
+
+ )
+}
diff --git a/src/app/(main)/resources/[category]/blur-corner.webp b/src/app/(main)/resources/[category]/blur-corner.webp
new file mode 100644
index 0000000000..50e58292e7
Binary files /dev/null and b/src/app/(main)/resources/[category]/blur-corner.webp differ
diff --git a/src/app/(main)/resources/[category]/cards-section.tsx b/src/app/(main)/resources/[category]/cards-section.tsx
new file mode 100644
index 0000000000..f2d89c8e69
--- /dev/null
+++ b/src/app/(main)/resources/[category]/cards-section.tsx
@@ -0,0 +1,107 @@
+import { clsx } from "clsx"
+
+import { Kind, ResourceMetadata, Topic } from "@/resources/types"
+import { Eyebrow } from "@/_design-system/eyebrow"
+import { Button } from "@/app/conf/_design-system/button"
+
+import { ResourceHubCard } from "../resource-hub-card"
+
+import {
+ categoriesConfig,
+ sectionKindNames,
+ sectionIds,
+} from "./categories-config"
+
+function sectionLabel(kind: Kind) {
+ return sectionKindNames[kind] ?? `${kind[0].toUpperCase()}${kind.slice(1)}`
+}
+
+export function CardsSection({
+ section,
+ category,
+ className,
+}: {
+ section: { kind: Kind; resources: ResourceMetadata[] }
+ category: Topic
+ className?: string
+}) {
+ const sectionData = categoriesConfig[category].sections[section.kind]
+ const heading = sectionData?.heading ?? sectionLabel(section.kind)
+ const text = sectionData?.text
+
+ let cta: React.ReactNode | undefined
+
+ if (section.kind === "video") {
+ cta = (
+
+ Go to Video Resources Library
+
+ )
+ }
+
+ return (
+
+
+
+
{sectionKindNames[section.kind]}
+
{heading}
+ {text && (
+
+ {text}
+
+ )}
+
+ {cta}
+
+
+
+ {section.resources.slice(0, 6).map(resource => (
+
+ tag !== section.kind)}
+ duration={resource.duration}
+ />
+
+ ))}
+
+ {section.resources.length > 6 && (
+
+ {/* we're using for SEO and Cmd+F support */}
+
+
+ Load more
+
+
+
+ {section.resources.slice(6).map(resource => {
+ return (
+
+ tag !== section.kind)}
+ duration={resource.duration}
+ />
+
+ )
+ })}
+
+
+ )}
+
+ )
+}
diff --git a/src/app/(main)/resources/[category]/categories-config.ts b/src/app/(main)/resources/[category]/categories-config.ts
new file mode 100644
index 0000000000..0493466cb9
--- /dev/null
+++ b/src/app/(main)/resources/[category]/categories-config.ts
@@ -0,0 +1,179 @@
+import { LearnPagePath } from "@/components/learn-aggregator/learn-pages"
+import { Kind, Topic } from "@/resources/types"
+
+// TODO: If the pages need to be customized further, consider flattening [category]/page.tsx
+// into multiple page files and defining the following texts in usual JSX.
+export const categoriesConfig: CategoriesConfig = {
+ frontend: {
+ heading: "Frontend",
+ subtitle: "Learn how to use GraphQL on the frontend.",
+ sections: {
+ video: {
+ heading: "Master GraphQL on the frontend",
+ text: "Watch talks and tutorials from GraphQL Conf and community experts. See how teams integrate GraphQL on the frontend and learn from real-world case studies.",
+ },
+ "tools-and-libraries": {
+ heading: "Frontend tools & libraries",
+ text: "Explore the most popular GraphQL client libraries and frameworks for frontend. These tools help you fetch and manage data with GraphQL.",
+ },
+ docs: {
+ heading: "Learn the basics",
+ text: "Learn practical GraphQL techniques for the frontend. Explore essential topics for building user interfaces.",
+ docs: [
+ "queries",
+ "mutations",
+ "subscriptions",
+ "validation",
+ "execution",
+ "response",
+ // best practices
+ "pagination",
+ ],
+ },
+ blog: {
+ heading: "Insights for frontend devs",
+ text: "Stay up to date with insights from the GraphQL community.",
+ },
+ },
+ },
+ backend: {
+ heading: "Backend",
+ subtitle:
+ "Build powerful GraphQL backends with the right tools, libraries and expert insights.",
+ sections: {
+ video: {
+ heading: "Master GraphQL on the backend",
+ text: "Discover videos and tutorials to help you build, deploy and scale your GraphQL backend.",
+ },
+ "tools-and-libraries": {
+ heading: "Backend tools & libraries",
+ text: "Find the right GraphQL backend stack — from JavaScript to Rust and beyond.",
+ },
+ docs: {
+ heading: "Lessons on the GraphQL backend",
+ text: "Build and run GraphQL servers — from defining a schema to handling production traffic.",
+ docs: [
+ "queries",
+ "mutations",
+ "subscriptions",
+ "validation",
+ "execution",
+ "response",
+ // best practices
+ "serving-over-http",
+ "file-uploads",
+ "pagination",
+ "performance",
+ "debug-errors",
+ "caching",
+ ],
+ },
+ blog: {
+ heading: "Build better GraphQL infrastructure",
+ text: "Dive into articles on server architecture, schema design and best practices for running GraphQL at scale.",
+ },
+ },
+ },
+ federation: {
+ heading: "Federation",
+ subtitle: "Learn how to build and compose GraphQL graphs with federation.",
+ sections: {
+ video: {
+ heading: "Master GraphQL federation",
+ text: "Watch talks and tutorials from GraphQL Conf and community experts. See how teams build and compose GraphQL graphs with federation.",
+ },
+ "tools-and-libraries": {
+ heading: "Tools & libraries for federated graphs",
+ text: "Run federated GraphQL graphs at scale with the right tools — from open-source routers to managed platforms.",
+ },
+ blog: {
+ heading: "Latest updates on federation & composition",
+ text: "Read the latest announcements and technical deep dives.",
+ },
+ },
+ },
+ ai: {
+ heading: "Artificial Intelligence",
+ subtitle: "Explore how to use GraphQL for AI systems.",
+ sections: {
+ "tools-and-libraries": {
+ heading: "GraphQL tools for AI",
+ text: "Discover the best tools for building AI systems with GraphQL.",
+ },
+ blog: {
+ heading: "Latest insights on AI & GraphQL",
+ text: "Read the latest announcements and technical deep dives.",
+ },
+ },
+ },
+ security: {
+ heading: "Security",
+ subtitle: "Learn how to secure your GraphQL APIs.",
+ sections: {
+ "tools-and-libraries": {
+ heading: "GraphQL security tools",
+ text: "Find resources to help secure GraphQL APIs across various languages and frameworks.",
+ },
+ docs: {
+ heading: "Security in practice",
+ text: "Follow proven patterns to delegate authorization correctly and protect your GraphQL APIs from malicious operations.",
+ },
+ },
+ },
+ monitoring: {
+ heading: "Monitoring",
+ subtitle:
+ "Stay ahead of issues by monitoring queries and watching error trends.",
+ sections: {
+ "tools-and-libraries": {
+ heading: "GraphQL monitoring tools",
+ text: "Connect GraphQL tracing and alerting systems to reduce blind spots in production.",
+ },
+ docs: {
+ heading: "Monitoring in practice",
+ text: "Learn how to track the right signals in your GraphQL ecosystem — from latency and error rates to resolver-level performance.",
+ },
+ "blog-or-newsletter": {
+ heading: "Latest insights on monitoring",
+ text: "Read the latest announcements and technical deep dives.",
+ },
+ },
+ },
+}
+
+export const sectionKindNames: Record
= {
+ video: "Featured videos",
+ blog: "Blog posts",
+ "tools-and-libraries": "Tools & Libraries",
+ guide: "Guides",
+ book: "Books",
+ "blog-or-newsletter": "Blogs & Newsletters",
+ docs: "Documentation",
+}
+
+export function slugify(name: string): string {
+ return name.toLowerCase().replace(/ & /g, "-and-").replace(/ /g, "-")
+}
+
+export const sectionIds: Record = Object.fromEntries(
+ Object.entries(sectionKindNames).map(([kind, name]) => [kind, slugify(name)]),
+) as Record
+
+type CategoriesConfig = {
+ [key in Topic]: {
+ heading: string
+ subtitle: string
+ sections: {
+ [key in Kind]?: {
+ heading: string
+ text: string
+ }
+ } & {
+ docs?: {
+ heading: string
+ text: string
+ docs?: LearnPagePath[]
+ }
+ }
+ }
+}
diff --git a/src/app/(main)/resources/[category]/category-tools-libraries-section.tsx b/src/app/(main)/resources/[category]/category-tools-libraries-section.tsx
new file mode 100644
index 0000000000..dc191e52cc
--- /dev/null
+++ b/src/app/(main)/resources/[category]/category-tools-libraries-section.tsx
@@ -0,0 +1,272 @@
+import path from "node:path"
+import { glob } from "node:fs/promises"
+import { readFile } from "node:fs/promises"
+
+import matter from "gray-matter"
+import type { CSSProperties } from "react"
+import { clsx } from "clsx"
+
+import { Button } from "@/app/conf/_design-system/button"
+import blurCorner from "./blur-corner.webp"
+import { Eyebrow } from "@/_design-system/eyebrow"
+import slugMap from "@/code/slug-map.json"
+import { type Topic } from "@/resources/types"
+import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
+
+import { IconSpritesheet, IconName } from "./spritesheet"
+import CaretDown from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr"
+
+interface LibraryEntry {
+ name: string
+ href?: string
+ group: string
+ tags: string[]
+}
+
+const librariesPromise = loadLibraries()
+
+async function loadLibraries(): Promise {
+ const entries: LibraryEntry[] = []
+
+ for await (const file of glob("src/code/**/*.md")) {
+ const relative = path.relative("src/code", file)
+ const segments = relative.split(path.sep)
+ const top = segments[0]
+ const group =
+ top === "language-support" ? (segments[1] ?? "language-support") : top
+ if (!group) continue
+
+ const raw = await readFile(file, "utf8")
+ const { data } = matter(raw)
+ const tags: string[] = Array.isArray(data.tags) ? data.tags : []
+ if (!tags.includes("tools-and-libraries")) continue
+
+ const name: string | undefined = data.name
+ if (!name) continue
+
+ const href: string | undefined =
+ data.url ??
+ (data.github ? `https://github.com/${data.github}` : undefined) ??
+ (data.npm ? `https://npmjs.com/package/${data.npm}` : undefined)
+
+ entries.push({ name, href, group, tags })
+ }
+
+ const deduped = entries.filter(
+ (item, index, self) =>
+ index ===
+ self.findIndex(t => t.name.toLowerCase() === item.name.toLowerCase()),
+ )
+
+ return deduped
+}
+
+function displayName(id: string) {
+ const key = id as keyof typeof slugMap
+ return slugMap[key] ?? id
+}
+
+export async function CategoryToolsLibrariesSection({
+ category,
+ className,
+}: {
+ category: Topic
+ className?: string
+}) {
+ const libraries = await librariesPromise
+ const filtered = libraries.filter(item => item.tags.includes(category))
+
+ const sortedGroups = Array.from(
+ filtered.reduce>((acc, item) => {
+ const list = acc.get(item.group) ?? []
+ list.push(item)
+ acc.set(item.group, list)
+ return acc
+ }, new Map()),
+ )
+ .map(([group, items]) => ({
+ id: group,
+ name: displayName(group),
+ items: items
+ .sort((a, b) =>
+ a.name.localeCompare(b.name, "en", { sensitivity: "base" }),
+ )
+ .slice(0, 20),
+ }))
+ .sort((a, b) => b.items.length - a.items.length)
+
+ const grouped: GroupData[] = sortedGroups.map((group, index) => {
+ const nextLength = sortedGroups[index + 1]?.items.length ?? 0
+ const columns =
+ nextLength > 0 && group.items.length >= nextLength * 1.9 ? 2 : 1
+ const breakIndex = columns === 2 ? Math.ceil(group.items.length / 2) : 0
+ return { ...group, columns, breakIndex }
+ })
+
+ if (grouped.length === 0) {
+ return null
+ }
+
+ return (
+
+ )
+}
+
+interface GroupData {
+ id: string
+ name: string
+ items: LibraryEntry[]
+ columns: 1 | 2
+ breakIndex: number
+}
+
+function distributeToColumns(groups: GroupData[]): [GroupData[], GroupData[]] {
+ const left: GroupData[] = []
+ const right: GroupData[] = []
+
+ let leftHeight = 0
+ let rightHeight = 0
+
+ for (const group of groups) {
+ const itemRows =
+ group.columns === 2
+ ? Math.ceil(group.items.length / 2)
+ : group.items.length
+ const height = itemRows + 1
+ if (leftHeight <= rightHeight) {
+ left.push(group)
+ leftHeight += height
+ } else {
+ right.push(group)
+ rightHeight += height
+ }
+ }
+
+ return [left, right]
+}
+
+function Group({ group }: { group: GroupData }) {
+ return (
+
+
+
+
+
+
+ {group.name}
+
+
+
+
+
+ {group.items.map((item, i) => (
+ = group.breakIndex ? "1px" : "",
+ }
+ : {}
+ }
+ >
+ {item.href ? (
+
+ {item.name}
+
+ ) : (
+
+ {item.name}
+
+ )}
+
+ ))}
+
+
+ )
+}
+
+function Stripes() {
+ return (
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/[category]/docs-section.tsx b/src/app/(main)/resources/[category]/docs-section.tsx
new file mode 100644
index 0000000000..2ccc0e3122
--- /dev/null
+++ b/src/app/(main)/resources/[category]/docs-section.tsx
@@ -0,0 +1,93 @@
+import { clsx } from "clsx"
+
+import { Button } from "@/app/conf/_design-system/button"
+import { Eyebrow } from "@/_design-system/eyebrow"
+import { partition } from "@/app/conf/_design-system/utils/partition"
+import { TeaserSectionListItem } from "@/components/learn-aggregator/teaser-section-list-item"
+import {
+ LearnPageItem,
+ LearnPagePath,
+ learnPages,
+} from "@/components/learn-aggregator/learn-pages"
+
+import { sectionIds } from "./categories-config"
+
+export interface DocsSectionProps {
+ heading: string
+ text: string
+ docs?: LearnPagePath[]
+ className?: string
+}
+
+export function DocsSection({
+ heading,
+ text,
+ docs,
+ className,
+}: DocsSectionProps) {
+ const pages =
+ docs?.map(path => learnPages[path]).filter(page => page !== null) ?? []
+
+ const [gettingStarted, bestPractices] = partition(
+ pages,
+ page => page.section === "getting-started",
+ )
+
+ return (
+
+
+
+
Documentation
+
{heading}
+
+ {text}
+
+
+
+ Go to Learn
+
+
+
+ {gettingStarted && (
+ <>
+ Getting Started
+
+ {gettingStarted.map((page, index) => (
+ }
+ section={page.section}
+ href={page.href}
+ />
+ ))}
+
+ >
+ )}
+ {bestPractices && (
+ <>
+ Best Practices
+
+ {bestPractices.map((page, index) => (
+ }
+ section={page.section}
+ href={page.href}
+ />
+ ))}
+
+ >
+ )}
+
+ )
+}
diff --git a/src/app/(main)/resources/[category]/page.tsx b/src/app/(main)/resources/[category]/page.tsx
new file mode 100644
index 0000000000..b1cd1991f3
--- /dev/null
+++ b/src/app/(main)/resources/[category]/page.tsx
@@ -0,0 +1,209 @@
+import { Metadata } from "next"
+import { notFound } from "next/navigation"
+import type { Item } from "nextra/normalize-pages"
+
+import { NavbarFixed } from "@/components/navbar/navbar-fixed"
+import { getResourcesByTag } from "@/resources/data"
+import {
+ Kind,
+ kinds,
+ topics,
+ type ResourceMetadata,
+ type Topic,
+} from "@/resources/types"
+
+import { ResourcesHero } from "../resources-hero"
+import { TocHeroContents } from "@/components/toc-hero"
+import { BlogPostsSection } from "./blog-posts-section"
+import { CategoryToolsLibrariesSection } from "./category-tools-libraries-section"
+import { Breadcrumbs } from "@/_design-system/breadcrumbs"
+
+import { sectionKindNames, categoriesConfig } from "./categories-config"
+import { CardsSection } from "./cards-section"
+import { DocsSection } from "./docs-section"
+import { LookingForMore } from "@/components/looking-for-more"
+import { unsafeKeys } from "@/app/conf/_design-system/utils/unsafe-keys"
+
+interface PageParams {
+ category: string
+}
+
+export async function generateStaticParams() {
+ return topics.map(category => ({ category }))
+}
+
+export async function generateMetadata({
+ params,
+}: {
+ params: PageParams
+}): Promise {
+ const category = params.category as Topic
+ if (!topics.includes(category)) return {}
+
+ const title = `${categoriesConfig[category].heading} Resources`
+ const description = categoriesConfig[category].subtitle
+
+ return { title, description }
+}
+
+export default async function CategoryPage({ params }: { params: PageParams }) {
+ const category = params.category as Topic
+ if (!topics.includes(category)) return notFound()
+
+ let sections = unsafeKeys(categoriesConfig[category].sections)
+ const resources = await getResourcesByTag(category)
+ const deduped = uniqueByTitle(resources)
+ const grouped = groupByKind(deduped)
+
+ if (sections.length === 0) sections = grouped.map(group => group.kind)
+
+ const activePath: Item[] = [
+ {
+ name: "Home",
+ route: "/",
+ },
+ {
+ name: "Resource Hub",
+ route: "/resources",
+ },
+ {
+ name: categoriesConfig[category].heading,
+ route: "",
+ },
+ ].map(item => ({
+ ...item,
+ title: item.name,
+ type: "page",
+ children: [],
+ frontMatter: {},
+ }))
+
+ return (
+
+
+
+
+
+
+
+
+
+ {sections.map(key => {
+ const data = grouped.find(group => group.kind === key)
+
+ return (
+
+ )
+ })}
+
+
+
+ )
+}
+
+function uniqueByTitle(resources: ResourceMetadata[]) {
+ const seen = new Set()
+ return resources.filter(resource => {
+ const key = resource.title.trim().toLowerCase()
+ if (seen.has(key)) return false
+ seen.add(key)
+ return true
+ })
+}
+
+function groupByKind(resources: ResourceMetadata[]) {
+ return kinds
+ .map(kind => ({
+ kind,
+ resources: resources.filter(
+ resource => (resource.kind ?? getKindFromTags(resource)) === kind,
+ ),
+ }))
+ .filter(section => section.resources.length > 0)
+}
+
+function getKindFromTags(resource: ResourceMetadata) {
+ return kinds.find(kind => resource.tags.includes(kind))
+}
+
+function sectionLabel(kind: Kind) {
+ return sectionKindNames[kind] ?? `${kind[0].toUpperCase()}${kind.slice(1)}`
+}
+
+function CategorySection({
+ section,
+ category,
+ className,
+}: {
+ section: { kind: Kind; resources: ResourceMetadata[] }
+ category: Topic
+ className?: string
+}) {
+ switch (section.kind) {
+ case "tools-and-libraries":
+ return (
+
+ )
+
+ case "blog": {
+ const blogSection = categoriesConfig[category].sections["blog"]
+
+ return (
+ ({
+ href: resource.url,
+ title: resource.title,
+ author: resource.author ?? "GraphQL Community",
+ tags: resource.tags.filter(
+ tag => tag !== "blog" && tag !== category,
+ ),
+ }))}
+ className={className}
+ />
+ )
+ }
+
+ case "docs": {
+ const docsSection = categoriesConfig[category].sections.docs
+ if (!docsSection) return null
+ return
+ }
+
+ default:
+ return (
+
+ )
+ }
+}
diff --git a/src/app/(main)/resources/[category]/spritesheet/index.tsx b/src/app/(main)/resources/[category]/spritesheet/index.tsx
new file mode 100644
index 0000000000..47eef9a0d1
--- /dev/null
+++ b/src/app/(main)/resources/[category]/spritesheet/index.tsx
@@ -0,0 +1,40 @@
+import type { SVGProps } from "react"
+
+import sheet from "./sheet.svg?resource"
+
+export type IconName =
+ | "ballerina"
+ | "c-net"
+ | "clojure"
+ | "elixir"
+ | "elm"
+ | "flutter"
+ | "go"
+ | "haskell"
+ | "java"
+ | "javascript"
+ | "julia"
+ | "multiplatform"
+ | "php"
+ | "python"
+ | "ruby"
+ | "rust"
+ | "scala"
+ | "swift"
+
+interface IconSpritesheetProps extends SVGProps {
+ sprite: IconName
+}
+
+export function IconSpritesheet({ sprite, ...props }: IconSpritesheetProps) {
+ return (
+ <>
+
+
+
+ >
+ )
+}
diff --git a/src/app/(main)/resources/[category]/spritesheet/sheet.svg b/src/app/(main)/resources/[category]/spritesheet/sheet.svg
new file mode 100644
index 0000000000..33545c32f1
--- /dev/null
+++ b/src/app/(main)/resources/[category]/spritesheet/sheet.svg
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/ai.svg b/src/app/(main)/resources/assets/ai.svg
new file mode 100644
index 0000000000..1a74a15a0e
--- /dev/null
+++ b/src/app/(main)/resources/assets/ai.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/archive.svg b/src/app/(main)/resources/assets/archive.svg
new file mode 100644
index 0000000000..bb98c0c8e5
--- /dev/null
+++ b/src/app/(main)/resources/assets/archive.svg
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/src/app/(main)/resources/assets/backend.svg b/src/app/(main)/resources/assets/backend.svg
new file mode 100644
index 0000000000..2477c25f58
--- /dev/null
+++ b/src/app/(main)/resources/assets/backend.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/bookmark.svg b/src/app/(main)/resources/assets/bookmark.svg
new file mode 100644
index 0000000000..422dc51a2a
--- /dev/null
+++ b/src/app/(main)/resources/assets/bookmark.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/federation.svg b/src/app/(main)/resources/assets/federation.svg
new file mode 100644
index 0000000000..e16b30d1a2
--- /dev/null
+++ b/src/app/(main)/resources/assets/federation.svg
@@ -0,0 +1,11 @@
+
+
+
diff --git a/src/app/(main)/resources/assets/frontend.svg b/src/app/(main)/resources/assets/frontend.svg
new file mode 100644
index 0000000000..135bf7899a
--- /dev/null
+++ b/src/app/(main)/resources/assets/frontend.svg
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/src/app/(main)/resources/assets/monitoring.svg b/src/app/(main)/resources/assets/monitoring.svg
new file mode 100644
index 0000000000..aa9ce67345
--- /dev/null
+++ b/src/app/(main)/resources/assets/monitoring.svg
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/src/app/(main)/resources/assets/newspaper.svg b/src/app/(main)/resources/assets/newspaper.svg
new file mode 100644
index 0000000000..0bc736695f
--- /dev/null
+++ b/src/app/(main)/resources/assets/newspaper.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/security.svg b/src/app/(main)/resources/assets/security.svg
new file mode 100644
index 0000000000..c999cc8256
--- /dev/null
+++ b/src/app/(main)/resources/assets/security.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/tools.svg b/src/app/(main)/resources/assets/tools.svg
new file mode 100644
index 0000000000..e22e782c3d
--- /dev/null
+++ b/src/app/(main)/resources/assets/tools.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/app/(main)/resources/assets/video-player.svg b/src/app/(main)/resources/assets/video-player.svg
new file mode 100644
index 0000000000..6a01b6f929
--- /dev/null
+++ b/src/app/(main)/resources/assets/video-player.svg
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/src/app/(main)/resources/assets/write-note.svg b/src/app/(main)/resources/assets/write-note.svg
new file mode 100644
index 0000000000..6c75219572
--- /dev/null
+++ b/src/app/(main)/resources/assets/write-note.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/src/app/(main)/resources/blog-category-links.tsx b/src/app/(main)/resources/blog-category-links.tsx
new file mode 100644
index 0000000000..fc22f0d747
--- /dev/null
+++ b/src/app/(main)/resources/blog-category-links.tsx
@@ -0,0 +1,44 @@
+"use client"
+
+import Link from "next/link"
+import { Collapsible } from "@base-ui-components/react/collapsible"
+
+import CaretDownIcon from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr"
+import { BlogTags } from "@/components/blog-page/blog-tags"
+import { blogCategories } from "@/components/blog-page/blog-categories"
+
+/**
+ * Shows tags on desktop and a collapsible on mobile.
+ */
+export function BlogCategoryLinks() {
+ return (
+ <>
+
+
+ categories
+
+
+
+ {blogCategories.map(category => (
+
+ {category.replace(/-/g, " ")}
+
+ ))}
+
+
+
+
+ >
+ )
+}
diff --git a/src/app/(main)/resources/blog-post-list-item.tsx b/src/app/(main)/resources/blog-post-list-item.tsx
new file mode 100644
index 0000000000..9dcf236926
--- /dev/null
+++ b/src/app/(main)/resources/blog-post-list-item.tsx
@@ -0,0 +1,53 @@
+import Link from "next/link"
+
+import ArrowRightIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+import { BlogTags } from "@/components/blog-page/blog-tags"
+
+export interface BlogPostRowProps {
+ date: string
+ category: string
+ title: string
+ href: string
+ author: string
+}
+
+export function BlogPostListItem({
+ date,
+ category,
+ title,
+ href,
+ author,
+}: BlogPostRowProps) {
+ const formattedDate = new Date(date)
+ .toLocaleDateString("en-GB", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ })
+ .replaceAll("/", "-")
+
+ return (
+
+
+
+
+
+ {title}
+
+
+
+
+ {formattedDate}
+
+
+ {author}
+
+
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/blog-section.tsx b/src/app/(main)/resources/blog-section.tsx
new file mode 100644
index 0000000000..3978ab3a1c
--- /dev/null
+++ b/src/app/(main)/resources/blog-section.tsx
@@ -0,0 +1,102 @@
+import fs from "node:fs/promises"
+import path from "node:path"
+import grayMatter from "gray-matter"
+
+import { Button } from "@/app/conf/_design-system/button"
+import PlayIcon from "@/app/conf/_design-system/pixelarticons/play.svg?svgr"
+
+import { BlogCategoryLinks } from "./blog-category-links"
+import { BlogPostListItem } from "./blog-post-list-item"
+import { blogCategories } from "@/components/blog-page/blog-categories"
+
+interface BlogFrontMatter {
+ title: string
+ tags?: string[]
+ byline: string
+ date: string | number | Date
+}
+
+type BlogFrontMatterWithFile = BlogFrontMatter & {
+ fileName: string
+ date: Date
+}
+
+let cachedBlogFrontMatters: BlogFrontMatterWithFile[] | null = null
+
+async function getBlogFrontMatters() {
+ if (cachedBlogFrontMatters) return cachedBlogFrontMatters
+
+ const files = await fs.readdir("./src/pages/blog")
+
+ const blogs = await Promise.all(
+ files
+ .filter(filename => /\.mdx?$/.test(filename))
+ .map(async (filename: string) => {
+ const filePath = path.join("./src/pages/blog", filename)
+ const content = await fs.readFile(filePath, "utf8")
+ const { data } = grayMatter(content)
+ const frontMatter = data as BlogFrontMatter
+
+ return {
+ ...frontMatter,
+ fileName: path.parse(filePath).name,
+ date: new Date(frontMatter.date),
+ }
+ }),
+ )
+
+ cachedBlogFrontMatters = blogs
+ .filter((blog): blog is BlogFrontMatterWithFile =>
+ Boolean(blog.fileName && blog.title && blog.date),
+ )
+ .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
+
+ return cachedBlogFrontMatters
+}
+
+export async function BlogSection() {
+ const blogs = await getBlogFrontMatters()
+ const blogPosts = blogCategories
+ .flatMap(tag => blogs.filter(blog => blog.tags?.includes(tag)).slice(0, 5))
+ .reduce((unique, blog) => {
+ if (!unique.some(item => item.fileName === blog.fileName)) {
+ unique.push(blog)
+ }
+ return unique
+ }, [])
+ .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
+ .slice(0, 5)
+
+ return (
+
+
+
+
+
+
+ {blogPosts.map(post => (
+
+ ))}
+
+
+
+ Read all posts
+
+
+ )
+}
diff --git a/src/app/(main)/resources/categories-section.tsx b/src/app/(main)/resources/categories-section.tsx
new file mode 100644
index 0000000000..ebaa6df132
--- /dev/null
+++ b/src/app/(main)/resources/categories-section.tsx
@@ -0,0 +1,120 @@
+import Link from "next/link"
+
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+
+import { Eyebrow } from "@/_design-system/eyebrow"
+import { type Topic } from "@/resources/types"
+
+import FrontendIcon from "./assets/frontend.svg?svgr"
+import BackendIcon from "./assets/backend.svg?svgr"
+import FederationIcon from "./assets/federation.svg?svgr"
+import SecurityIcon from "./assets/security.svg?svgr"
+import AIIcon from "./assets/ai.svg?svgr"
+import MonitoringIcon from "./assets/monitoring.svg?svgr"
+
+interface Category {
+ id: Topic
+ name: string
+ description: string
+ icon: React.ReactNode
+}
+
+const categories: Category[] = [
+ {
+ id: "frontend",
+ name: "Frontend",
+ description:
+ "Build better queries and optimize UI performance with the right client tools.",
+ icon: (
+
+ ),
+ },
+ {
+ id: "backend",
+ name: "Backend",
+ description:
+ "From resolvers to execution — everything you need to run a GraphQL server in production.",
+ icon: (
+
+ ),
+ },
+ {
+ id: "federation",
+ name: "Federation",
+ description:
+ "Design and manage distributed graphs that scale across teams and services.",
+ icon: (
+
+ ),
+ },
+ {
+ id: "security",
+ name: "Security",
+ description:
+ "Secure your GraphQL API with query limits and schema protection.",
+ icon: (
+
+ ),
+ },
+ {
+ id: "ai",
+ name: "AI",
+ description:
+ "Use GraphQL to power AI systems — patterns, tools and implementations.",
+ icon: (
+
+ ),
+ },
+ {
+ id: "monitoring",
+ name: "Monitoring",
+ description:
+ "Track performance, usage and schema changes to keep your graph healthy.",
+ icon: (
+
+ ),
+ },
+]
+
+export function CategoriesSection() {
+ return (
+
+
+
+
+ {categories.map(category => (
+
+ ))}
+
+
+ )
+}
+
+function CategoryCard({ category }: { category: Category }) {
+ return (
+
+
+
+
{category.name}
+
+ {category.description}
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/keep-learning.tsx b/src/app/(main)/resources/keep-learning.tsx
new file mode 100644
index 0000000000..178afc20ca
--- /dev/null
+++ b/src/app/(main)/resources/keep-learning.tsx
@@ -0,0 +1,55 @@
+import { clsx } from "clsx"
+
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
+import { Anchor } from "@/app/conf/_design-system/anchor"
+
+import blurCorner from "./[category]/blur-corner.webp"
+
+export function KeepLearning({
+ title,
+ href,
+ stripes,
+ className,
+}: {
+ title: string
+ href: string
+ stripes: string
+ className?: string
+}) {
+ return (
+
+ Keep Learning
+
+
+ Next
+
+
+ {title}
+
+
+
+ )
+}
+
+function Stripes({ stripes }: { stripes: string }) {
+ return (
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/page.tsx b/src/app/(main)/resources/page.tsx
new file mode 100644
index 0000000000..8cb5aa3652
--- /dev/null
+++ b/src/app/(main)/resources/page.tsx
@@ -0,0 +1,47 @@
+import { NavbarFixed } from "@/components/navbar/navbar-fixed"
+import { LookingForMore } from "@/components/looking-for-more"
+
+import { ResourcesHero } from "./resources-hero"
+import { CategoriesSection } from "./categories-section"
+import { ToolsLibrariesSection } from "./tools-libraries-section"
+import { SpecificationSection } from "./specification-section"
+import { BlogSection } from "./blog-section"
+import { VideoResourcesSection } from "./video-resources-section"
+import { ReadingResourcesSection } from "./reading-resources-section"
+
+export const metadata = {
+ title: "Resource Hub",
+ description:
+ "Explore curated GraphQL resources by topic. Find tools, videos, blog posts, and more to help you build with GraphQL.",
+}
+
+export default function ResourcesPage() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/reading-resources-section.tsx b/src/app/(main)/resources/reading-resources-section.tsx
new file mode 100644
index 0000000000..daf6d6227c
--- /dev/null
+++ b/src/app/(main)/resources/reading-resources-section.tsx
@@ -0,0 +1,71 @@
+import Link from "next/link"
+
+import { Button } from "@/app/conf/_design-system/button"
+import { Eyebrow } from "@/_design-system/eyebrow"
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+
+import NewspaperIcon from "./assets/newspaper.svg?svgr"
+import WriteIcon from "./assets/write-note.svg?svgr"
+import BookIcon from "./assets/bookmark.svg?svgr"
+
+export function ReadingResourcesSection() {
+ return (
+
+
+
+
reading resources library
+
+
+ Dive into GraphQL content
+
+
+ Browse reading materials to learn best practices and stay up to date
+ with the ecosystem.
+
+
+ Explore reading resources
+
+
+
+
+ }
+ label="Blogs and newsletters"
+ />
+ }
+ label="Individual posts"
+ />
+ }
+ label="Books"
+ />
+
+
+
+ )
+}
+
+function ReadingLink({
+ href,
+ icon,
+ label,
+}: {
+ href: string
+ icon: React.ReactNode
+ label: string
+}) {
+ return (
+
+ {icon}
+ {label}
+
+
+ )
+}
diff --git a/src/app/(main)/resources/reading/[subcategory]/page.tsx b/src/app/(main)/resources/reading/[subcategory]/page.tsx
new file mode 100644
index 0000000000..12ca5b273f
--- /dev/null
+++ b/src/app/(main)/resources/reading/[subcategory]/page.tsx
@@ -0,0 +1,32 @@
+import { notFound } from "next/navigation"
+
+import { ReadingLibraryPage, readingMetadata } from "../reading-page"
+import { subcategories, type Subcategory } from "../reading-page-categories"
+
+interface PageParams {
+ subcategory: string
+}
+
+function isSubcategory(value: string): value is Subcategory {
+ return subcategories.includes(value as Subcategory)
+}
+
+export function generateStaticParams() {
+ return subcategories.map(subcategory => ({ subcategory }))
+}
+
+export function generateMetadata({ params }: { params: PageParams }) {
+ const subcategory = params.subcategory
+ if (!isSubcategory(subcategory)) return {}
+ return readingMetadata(subcategory)
+}
+
+export default function ReadingSubcategoryPage({
+ params,
+}: {
+ params: PageParams
+}) {
+ const subcategory = params.subcategory
+ if (!isSubcategory(subcategory)) return notFound()
+ return
+}
diff --git a/src/app/(main)/resources/reading/page.tsx b/src/app/(main)/resources/reading/page.tsx
new file mode 100644
index 0000000000..a997ace6c3
--- /dev/null
+++ b/src/app/(main)/resources/reading/page.tsx
@@ -0,0 +1,7 @@
+import { ReadingLibraryPage, readingMetadata } from "./reading-page"
+
+export const metadata = readingMetadata("all")
+
+export default function ReadingPage() {
+ return
+}
diff --git a/src/app/(main)/resources/reading/reading-page-categories.tsx b/src/app/(main)/resources/reading/reading-page-categories.tsx
new file mode 100644
index 0000000000..2ce2207968
--- /dev/null
+++ b/src/app/(main)/resources/reading/reading-page-categories.tsx
@@ -0,0 +1,43 @@
+import NewspaperIcon from "../assets/newspaper.svg?svgr"
+import WriteIcon from "../assets/write-note.svg?svgr"
+import BookIcon from "../assets/bookmark.svg?svgr"
+
+export const subcategories = [
+ "blogs-and-newsletters",
+ "individual-posts",
+ "books",
+] as const
+
+export type Subcategory = (typeof subcategories)[number]
+
+export type ReadingPageTab = Subcategory | "all"
+
+export const tabs: {
+ label: string
+ href: string
+ variant: ReadingPageTab
+ color: string
+ icon: React.ReactNode
+}[] = [
+ {
+ label: "Blogs & newsletters",
+ href: "/resources/reading/blogs-and-newsletters",
+ variant: "blogs-and-newsletters",
+ color: "hsl(var(--color-pri-base))",
+ icon: ,
+ },
+ {
+ label: "Individual posts",
+ href: "/resources/reading/individual-posts",
+ variant: "individual-posts",
+ color: "#FF8800",
+ icon: ,
+ },
+ {
+ label: "Books",
+ href: "/resources/reading/books",
+ variant: "books",
+ color: "#00C6AC",
+ icon: ,
+ },
+]
diff --git a/src/app/(main)/resources/reading/reading-page.tsx b/src/app/(main)/resources/reading/reading-page.tsx
new file mode 100644
index 0000000000..81d970a33d
--- /dev/null
+++ b/src/app/(main)/resources/reading/reading-page.tsx
@@ -0,0 +1,222 @@
+import Link from "next/link"
+import { notFound } from "next/navigation"
+import { clsx } from "clsx"
+
+import { NavbarFixed } from "@/components/navbar/navbar-fixed"
+import { Breadcrumbs } from "@/_design-system/breadcrumbs"
+import { readResources } from "@/resources/data"
+import { topics, type ResourceMetadata, type Topic } from "@/resources/types"
+import { LookingForMore } from "@/components/looking-for-more"
+import { KeepLearning } from "../keep-learning"
+import { Button } from "@/app/conf/_design-system/button"
+
+import { tabs, type ReadingPageTab } from "./reading-page-categories"
+
+import { ResourcesHero } from "../resources-hero"
+import { ReadingResourcesCard } from "./reading-resources-card"
+
+const topicSet = new Set(topics)
+
+const variants: Record<
+ ReadingPageTab,
+ {
+ title: string
+ description: string
+ eyebrow: string
+ filter: (resource: ResourceMetadata) => boolean
+ }
+> = {
+ all: {
+ title: "Reading Resources Library",
+ description:
+ "Browse reading materials to learn best practices and stay up to date with the ecosystem.",
+ eyebrow: "Reading resources",
+ filter: resource =>
+ resource.tags.some(
+ tag =>
+ tag === "blog-or-newsletter" || tag === "guide" || tag === "book",
+ ),
+ },
+ "blogs-and-newsletters": {
+ title: "Blogs & Newsletters",
+ description:
+ "Popular sources to learn and keep track of the GraphQL ecosystem.",
+ eyebrow: "Stay informed",
+ filter: resource => resource.tags.includes("blog-or-newsletter"),
+ },
+ "individual-posts": {
+ title: "Individual Posts",
+ description: "Notable posts from the community.",
+ eyebrow: "Deep dives",
+ filter: resource =>
+ resource.tags.some(
+ tag =>
+ tag === "guide" ||
+ (tag === "blog" && !resource.url.startsWith("/blog")),
+ ),
+ },
+ books: {
+ title: "Books",
+ description:
+ "Books to help you level up your GraphQL knowledge and practice.",
+ eyebrow: "Read and learn",
+ filter: resource => resource.tags.includes("book"),
+ },
+}
+
+export function readingMetadata(variant: ReadingPageTab) {
+ const config = variants[variant]
+ if (!config) return {}
+ return {
+ title: config.title,
+ description: config.description,
+ }
+}
+
+function hasTopicTag(resource: ResourceMetadata) {
+ return resource.tags.some(tag => topicSet.has(tag as Topic))
+}
+
+function uniqueByTitle(resources: ResourceMetadata[]) {
+ const seen = new Set()
+ return resources.filter(resource => {
+ const key = resource.title.trim().toLowerCase()
+ if (seen.has(key)) return false
+ seen.add(key)
+ return true
+ })
+}
+
+export async function ReadingLibraryPage({
+ variant,
+}: {
+ variant: ReadingPageTab
+}) {
+ const config = variants[variant]
+ if (!config) return notFound()
+
+ const resources = await readResources()
+ const filtered = uniqueByTitle(resources)
+ .filter(config.filter)
+ .sort((a, b) =>
+ a.title.localeCompare(b.title, "en", { sensitivity: "base" }),
+ )
+
+ const activePath = [
+ {
+ name: "Home",
+ route: "/",
+ },
+ {
+ name: "Resource Hub",
+ route: "/resources",
+ },
+ {
+ name: "Reading Resources Library",
+ route: "/resources/reading",
+ },
+ ].map(item => ({
+ ...item,
+ title: item.name,
+ type: "page",
+ children: [],
+ frontMatter: {},
+ }))
+
+ return (
+
+
+
+
+
+
+
+ Select a category
+
+
+ {tabs.map(tab => {
+ const active = tab.variant === variant
+ return (
+
+ {tab.label}
+
+ )
+ })}
+
+
+ {filtered.slice(0, 9).map(resource => (
+
+
+
+ ))}
+
+ {filtered.length > 9 && (
+
+ {/* we're using for SEO and Cmd+F support */}
+
+
+ Load more
+
+
+
+ {filtered.slice(6).map(resource => {
+ return (
+
+
+
+ )
+ })}
+
+
+ )}
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/reading/reading-resources-card.tsx b/src/app/(main)/resources/reading/reading-resources-card.tsx
new file mode 100644
index 0000000000..4aecfb37c1
--- /dev/null
+++ b/src/app/(main)/resources/reading/reading-resources-card.tsx
@@ -0,0 +1,66 @@
+import type { ComponentType, SVGProps } from "react"
+
+import { ResourceHubCard } from "../resource-hub-card"
+import type { ResourceMetadata } from "@/resources/types"
+
+import NewspaperIcon from "../assets/newspaper.svg?svgr"
+import WriteIcon from "../assets/write-note.svg?svgr"
+import BookIcon from "../assets/bookmark.svg?svgr"
+
+type CornerIcon = ComponentType>
+
+type ReadingKind = "book" | "blog-or-newsletter" | "blog" | "guide"
+
+const readingKindConfig: Record<
+ ReadingKind,
+ { label: string; color: string; Icon: CornerIcon }
+> = {
+ book: { label: "books", color: "#00C6AC", Icon: BookIcon },
+ "blog-or-newsletter": {
+ label: "blogs & newsletters",
+ color: "hsl(var(--color-pri-base))",
+ Icon: NewspaperIcon,
+ },
+ blog: { label: "blog posts", color: "#FF8800", Icon: WriteIcon },
+ guide: { label: "guides", color: "#FF8800", Icon: WriteIcon },
+}
+
+function pickReadingKind(resource: ResourceMetadata): ReadingKind | undefined {
+ const candidates: ReadingKind[] = [
+ "book",
+ "blog-or-newsletter",
+ "guide",
+ "blog",
+ ]
+ return candidates.find((candidate): candidate is ReadingKind =>
+ resource.tags.includes(candidate),
+ )
+}
+
+export function ReadingResourcesCard({
+ resource,
+}: {
+ resource: ResourceMetadata
+}) {
+ const kind = pickReadingKind(resource)
+ const config = kind ? readingKindConfig[kind] : undefined
+
+ return (
+
+ ) : null
+ }
+ />
+ )
+}
diff --git a/src/app/(main)/resources/resource-hub-card.tsx b/src/app/(main)/resources/resource-hub-card.tsx
new file mode 100644
index 0000000000..31b1695ee6
--- /dev/null
+++ b/src/app/(main)/resources/resource-hub-card.tsx
@@ -0,0 +1,119 @@
+import Link from "next/link"
+import type { ReactNode } from "react"
+import { clsx } from "clsx"
+
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+import ClockIcon from "@/app/conf/_design-system/pixelarticons/clock.svg?svgr"
+import { Tag } from "@/app/conf/_design-system/tag"
+import { Topic } from "@/resources/types"
+import { tagColors } from "@/app/conf/_design-system/tag-colors"
+
+interface ResourceHubCardProps {
+ href: string
+ title: string
+ author?: string
+ duration?: string
+ authorPlacement?: "body" | "footer"
+ tags?: string[]
+ className?: string
+ icon?: ReactNode
+}
+
+export function ResourceHubCard({
+ href,
+ title,
+ author,
+ duration,
+ authorPlacement = "footer",
+ tags,
+ className,
+ icon,
+}: ResourceHubCardProps) {
+ return (
+
+
+
+ {tags?.length ? (
+
+ {tags.map(tag => (
+
+ {formatTag(tag)}
+
+ ))}
+
+ ) : null}
+
+ {authorPlacement === "body" && author ? (
+ {author}
+ ) : null}
+
100
+ ? "typography-body-lg"
+ : "typography-h4 md:typography-h3",
+ )}
+ >
+ {title}
+
+
+
+ {icon ? (
+
+ {icon}
+
+ ) : null}
+
+
+ {(authorPlacement === "footer" || !!duration) && (
+
+ {authorPlacement === "footer" && author ? (
+ {author}
+ ) : null}
+ {duration ? (
+
+
+ {duration}
+
+ ) : null}
+
+ )}
+
+
+
+ )
+}
+
+function formatTag(tag: string) {
+ if (tag === "blog-or-newsletter") return "Blogs & Newsletters"
+ if (tag === "book") return "Books"
+ if (tag === "guide") return "Individual posts"
+
+ return tag.replaceAll("-", " ")
+}
diff --git a/src/app/(main)/resources/resources-hero.tsx b/src/app/(main)/resources/resources-hero.tsx
new file mode 100644
index 0000000000..29ac61e94c
--- /dev/null
+++ b/src/app/(main)/resources/resources-hero.tsx
@@ -0,0 +1,28 @@
+import { LearnHeroStripes } from "@/components/learn-aggregator/learn-hero-stripes"
+
+export function ResourcesHero({
+ heading,
+ text,
+ children,
+}: {
+ heading: string
+ text: string
+ children?: React.ReactNode
+}) {
+ return (
+
+
+
+
{heading}
+
{text}
+ {children}
+
+
+ )
+}
diff --git a/src/app/(main)/resources/specification-section.tsx b/src/app/(main)/resources/specification-section.tsx
new file mode 100644
index 0000000000..45fc32edfe
--- /dev/null
+++ b/src/app/(main)/resources/specification-section.tsx
@@ -0,0 +1,54 @@
+import { Button } from "@/app/conf/_design-system/button"
+import ArchiveIcon from "./assets/archive.svg?svgr"
+import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
+import { Eyebrow } from "@/_design-system/eyebrow"
+
+export function SpecificationSection() {
+ return (
+
+
+
+
specification
+
+
+
+
+
+
+ Read the GraphQL Specification
+
+
+ The specification defines the core structure of GraphQL. It's the
+ foundation for building consistent servers, clients, and tools.
+ Read the spec to better understand how GraphQL works.
+
+
+ Go to specification
+
+
+
+
+
+ )
+}
+
+function Stripes() {
+ return (
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/tools-libraries-section.tsx b/src/app/(main)/resources/tools-libraries-section.tsx
new file mode 100644
index 0000000000..4c69c86096
--- /dev/null
+++ b/src/app/(main)/resources/tools-libraries-section.tsx
@@ -0,0 +1,34 @@
+import { Button } from "@/app/conf/_design-system/button"
+import ToolsIcon from "./assets/tools.svg?svgr"
+import { Eyebrow } from "@/_design-system/eyebrow"
+
+export function ToolsLibrariesSection() {
+ return (
+
+ )
+}
diff --git a/src/app/(main)/resources/video-resources-section.tsx b/src/app/(main)/resources/video-resources-section.tsx
new file mode 100644
index 0000000000..7816a8ff83
--- /dev/null
+++ b/src/app/(main)/resources/video-resources-section.tsx
@@ -0,0 +1,31 @@
+import { Button } from "@/app/conf/_design-system/button"
+import { Eyebrow } from "@/_design-system/eyebrow"
+import VideoPlayerIcon from "./assets/video-player.svg?svgr"
+
+export function VideoResourcesSection() {
+ return (
+
+ video resources library
+
+
+
+
+
+
+
+
+ Watch and learn GraphQL
+
+
+ Build your skills with featured videos from GraphQL Conf, global
+ meetups, and expert engineers — keeping you up to date in a
+ fast-moving ecosystem.
+
+
+ Go to Video Resources
+
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/video/page.tsx b/src/app/(main)/resources/video/page.tsx
new file mode 100644
index 0000000000..b845357422
--- /dev/null
+++ b/src/app/(main)/resources/video/page.tsx
@@ -0,0 +1,95 @@
+import { NavbarFixed } from "@/components/navbar/navbar-fixed"
+import { getResourcesByTag } from "@/resources/data"
+import { ResourcesHero } from "../resources-hero"
+import { VideoLibrary } from "./video-library"
+import { KeepLearning } from "../keep-learning"
+import { LookingForMore } from "@/components/looking-for-more"
+import { Breadcrumbs } from "@/_design-system/breadcrumbs"
+
+export const metadata = {
+ title: "Video Resources Library",
+ description:
+ "Expand your expertise with curated videos to help you master GraphQL and stay up to date with its evolving ecosystem.",
+}
+
+export default async function VideoResourcesPage() {
+ const resources = await getResourcesByTag("video")
+ const seen = new Set()
+ const unique = resources.filter(resource => {
+ const key = resource.title.trim().toLowerCase()
+ if (seen.has(key)) return false
+ seen.add(key)
+ return true
+ })
+ unique.sort((a, b) =>
+ a.title.localeCompare(b.title, "en", { sensitivity: "base" }),
+ )
+
+ return (
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/(main)/resources/video/video-library.tsx b/src/app/(main)/resources/video/video-library.tsx
new file mode 100644
index 0000000000..c126039953
--- /dev/null
+++ b/src/app/(main)/resources/video/video-library.tsx
@@ -0,0 +1,223 @@
+"use client"
+
+import { useMemo, useState } from "react"
+import { clsx } from "clsx"
+
+import { Button } from "@/app/conf/_design-system/button"
+import { Tag } from "@/app/conf/_design-system/tag"
+import CaretDownIcon from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr"
+import { type ResourceMetadata, topics, type Topic } from "@/resources/types"
+import { tagColors } from "@/app/conf/_design-system/tag-colors"
+
+import { ResourceHubCard } from "../resource-hub-card"
+
+interface VideoLibraryProps {
+ resources: ResourceMetadata[]
+ className?: string
+}
+
+type SortOrder = "az" | "za"
+
+export function VideoLibrary({ resources, className }: VideoLibraryProps) {
+ const [selectedTopics, setSelectedTopics] = useState([])
+ const [sortOrder, setSortOrder] = useState("az")
+
+ const topicOptions = useMemo(() => {
+ const allowed = new Set(topics)
+ const found = new Set()
+ resources.forEach(resource => {
+ resource.tags.forEach(tag => {
+ if (allowed.has(tag as Topic)) {
+ found.add(tag)
+ }
+ })
+ })
+ return Array.from(found).sort((a, b) =>
+ a.localeCompare(b, "en", { sensitivity: "base" }),
+ )
+ }, [resources])
+
+ const filtered = useMemo(() => {
+ const filteredByTopic =
+ selectedTopics.length === 0
+ ? resources
+ : resources.filter(resource =>
+ resource.tags.some(tag => selectedTopics.includes(tag)),
+ )
+
+ const sorted = [...filteredByTopic].sort((a, b) =>
+ sortOrder === "az"
+ ? a.title.localeCompare(b.title, "en", { sensitivity: "base" })
+ : b.title.localeCompare(a.title, "en", { sensitivity: "base" }),
+ )
+
+ return sorted
+ }, [resources, selectedTopics, sortOrder])
+
+ return (
+
+
+
+
+
+
+
+ Sort
+
+
+
+ setSortOrder(event.target.value as SortOrder)
+ }
+ className="typography-body-sm w-full appearance-none bg-transparent px-3 py-2 outline-none"
+ >
+ Title A–Z
+ Title Z–A
+
+
+
+
+
+
+
+
+ {filtered.slice(0, 6).map(resource => {
+ return (
+
+ tag !== "video")}
+ duration={resource.duration}
+ />
+
+ )
+ })}
+
+ {filtered.length > 6 && (
+
+ {/* we're using for SEO and Cmd+F support */}
+
+
+ Load more
+
+
+
+ {filtered.slice(6).map(resource => {
+ return (
+
+ tag !== "video")}
+ duration={resource.duration}
+ />
+
+ )
+ })}
+
+
+ )}
+
+ )
+}
+
+function TopicsFilter({
+ label,
+ options,
+ resources,
+ value,
+ onChange,
+}: {
+ label: string
+ options: string[]
+ resources: ResourceMetadata[]
+ value: string[]
+ onChange: (next: string[]) => void
+}) {
+ const topicCounts = useMemo(() => {
+ const counts: Record = {}
+ resources.forEach(resource => {
+ resource.tags.forEach(tag => {
+ if (options.includes(tag)) {
+ counts[tag] = (counts[tag] || 0) + 1
+ }
+ })
+ })
+ return counts
+ }, [resources, options])
+
+ const toggleTopic = (topic: string) => {
+ if (value.includes(topic)) {
+ onChange(value.filter(t => t !== topic))
+ } else {
+ onChange([...value, topic])
+ }
+ }
+
+ const hasSelection = value.length > 0
+
+ return (
+
+
+ {label}
+
+
+ {options.map((topic, i) => {
+ const isSelected = value.includes(topic)
+ const count = topicCounts[topic] || 0
+ return (
+
+ toggleTopic(topic)}
+ data-active={isSelected ? "" : undefined}
+ tabIndex={i === 0 ? 0 : -1}
+ className={clsx(
+ "gql-focus-visible -m-1 flex p-1 !outline-offset-0 ring-inset ring-neu-400 transition-opacity duration-75 hover:opacity-100 hover:ring dark:ring-neu-50",
+ hasSelection && !isSelected && "opacity-50",
+ )}
+ onKeyDown={arrowsMoveSideways}
+ >
+
+ {topic.replaceAll("-", " ")} ({count})
+
+
+
+ )
+ })}
+
+
+ )
+}
+
+function arrowsMoveSideways(event: React.KeyboardEvent) {
+ if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
+ const target = event.currentTarget as HTMLElement
+ const sibling =
+ event.key === "ArrowLeft"
+ ? target.parentElement?.previousElementSibling?.querySelector("button")
+ : target.parentElement?.nextElementSibling?.querySelector("button")
+ if (sibling instanceof HTMLElement) {
+ sibling.focus()
+ }
+ }
+}
diff --git a/src/app/conf/_design-system/pixelarticons/caret-down.svg b/src/app/conf/_design-system/pixelarticons/caret-down.svg
index 428cdbbaaf..deb68afbea 100644
--- a/src/app/conf/_design-system/pixelarticons/caret-down.svg
+++ b/src/app/conf/_design-system/pixelarticons/caret-down.svg
@@ -3,12 +3,11 @@
width="25"
height="24"
viewBox="0 0 25 24"
- fill="none"
+ fill="#A0A88A"
>
diff --git a/src/app/conf/_design-system/stripes-decoration.tsx b/src/app/conf/_design-system/stripes-decoration.tsx
index 8d03825612..f895baeada 100644
--- a/src/app/conf/_design-system/stripes-decoration.tsx
+++ b/src/app/conf/_design-system/stripes-decoration.tsx
@@ -1,21 +1,27 @@
import clsx from "clsx"
const maskEven =
- "repeating-linear-gradient(to right, transparent, transparent var(--stripe-width), black var(--stripe-width), black calc(var(--stripe-width) * 2))"
+ "repeating-linear-gradient(var(--angle), transparent, transparent var(--stripe-width), black var(--stripe-width), black calc(var(--stripe-width) * 2))"
const maskOdd =
- "repeating-linear-gradient(to right, black, black var(--stripe-width), transparent var(--stripe-width), transparent calc(var(--stripe-width) * 2))"
+ "repeating-linear-gradient(var(--angle), black, black var(--stripe-width), transparent var(--stripe-width), transparent calc(var(--stripe-width) * 2))"
export interface StripesDecorationProps {
evenClassName?: string
oddClassName?: string
stripeWidth?: string
+ /**
+ * @default "90deg" to right,
+ * use "-90deg" to align with right side of the container
+ */
+ angle?: string
}
export function StripesDecoration({
stripeWidth = "12px",
evenClassName,
oddClassName,
+ angle = "90deg",
}: StripesDecorationProps) {
return (
<>
@@ -23,7 +29,10 @@ export function StripesDecoration({
diff --git a/src/app/conf/_design-system/utils/partition.tsx b/src/app/conf/_design-system/utils/partition.tsx
new file mode 100644
index 0000000000..e8a143cb1b
--- /dev/null
+++ b/src/app/conf/_design-system/utils/partition.tsx
@@ -0,0 +1,24 @@
+export function partition(
+ array: T[],
+ predicate: (item: T) => item is X,
+): [X[], Exclude[]]
+export function partition(
+ array: T[],
+ predicate: (item: T) => boolean,
+): [T[], T[]]
+export function partition(
+ array: T[],
+ predicate: (item: T) => boolean,
+): [T[], T[]] {
+ const left: T[] = []
+ const right: T[] = []
+
+ for (const item of array) {
+ if (predicate(item)) {
+ left.push(item)
+ } else {
+ right.push(item)
+ }
+ }
+ return [left, right]
+}
diff --git a/src/app/conf/_design-system/utils/unsafe-keys.ts b/src/app/conf/_design-system/utils/unsafe-keys.ts
new file mode 100644
index 0000000000..c78699e7a2
--- /dev/null
+++ b/src/app/conf/_design-system/utils/unsafe-keys.ts
@@ -0,0 +1,3 @@
+export const unsafeKeys = Object.keys as (
+ obj: T,
+) => Array
diff --git a/src/code/language-support/ballerina/client/ballerina-graphql.md b/src/code/language-support/ballerina/client/ballerina-graphql.md
index 404990ac3f..ed23acd975 100644
--- a/src/code/language-support/ballerina/client/ballerina-graphql.md
+++ b/src/code/language-support/ballerina/client/ballerina-graphql.md
@@ -3,6 +3,10 @@ name: ballerina-graphql
description: The Ballerina Standard Library Package for consume GraphQL services.
url: https://lib.ballerina.io/ballerina/graphql/latest
github: ballerina-platform/module-ballerina-graphql
+tags:
+ - tools-and-libraries
+ - frontend
+ - frontend
---
To run a `ballerina-graphql` client:
diff --git a/src/code/language-support/ballerina/server/ballerina-graphql.md b/src/code/language-support/ballerina/server/ballerina-graphql.md
index b1010190a8..083f7b3bc2 100644
--- a/src/code/language-support/ballerina/server/ballerina-graphql.md
+++ b/src/code/language-support/ballerina/server/ballerina-graphql.md
@@ -3,6 +3,10 @@ name: ballerina-graphql
description: The Ballerina Standard Library Package for write GraphQL services.
url: https://lib.ballerina.io/ballerina/graphql/latest
github: ballerina-platform/module-ballerina-graphql
+tags:
+ - tools-and-libraries
+ - backend
+ - frontend
---
To run a `ballerina-graphql` hello world server:
diff --git a/src/code/language-support/c-c/client/cppgraphqlgen-clientgen.md b/src/code/language-support/c-c/client/cppgraphqlgen-clientgen.md
index 6787ed8d0c..3992a82cbe 100644
--- a/src/code/language-support/c-c/client/cppgraphqlgen-clientgen.md
+++ b/src/code/language-support/c-c/client/cppgraphqlgen-clientgen.md
@@ -2,6 +2,9 @@
name: cppgraphqlgen-clientgen
description: A C++20 GraphQL request client generator and response parser using the schema document. If you want to consume a GraphQL service from a C++ client, you can pre-compile queries and deserialization functions for the expected results.
github: microsoft/cppgraphqlgen
+tags:
+ - tools-and-libraries
+ - frontend
---
The `clientgen` utility is based on `schemagen` and shares the same external dependencies. The command line arguments
diff --git a/src/code/language-support/c-c/server/cppgraphqlgen-schemagen.md b/src/code/language-support/c-c/server/cppgraphqlgen-schemagen.md
index 106c67ef81..d29bb37534 100644
--- a/src/code/language-support/c-c/server/cppgraphqlgen-schemagen.md
+++ b/src/code/language-support/c-c/server/cppgraphqlgen-schemagen.md
@@ -2,6 +2,9 @@
name: cppgraphqlgen-schemagen
description: A C++20 GraphQL service generator using the schema document. You can use this to implement a GraphQL service with resolvers backed by whatever C++ libraries you need.
github: microsoft/cppgraphqlgen
+tags:
+ - tools-and-libraries
+ - backend
---
Run `schemagen -?` to get a list of options. Many of the files in the [samples](https://github.com/microsoft/cppgraphqlgen/tree/main/samples) directory were generated
diff --git a/src/code/language-support/c-c/tools/libgraphqlparser.md b/src/code/language-support/c-c/tools/libgraphqlparser.md
index 19b5b84c86..a78e3f6222 100644
--- a/src/code/language-support/c-c/tools/libgraphqlparser.md
+++ b/src/code/language-support/c-c/tools/libgraphqlparser.md
@@ -2,4 +2,7 @@
name: libgraphqlparser
description: A GraphQL query language parser in C++ with C and C++ APIs.
github: graphql/libgraphqlparser
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/c-net/client/graphql-client.md b/src/code/language-support/c-net/client/graphql-client.md
index 12013bcb2d..62650c7ad6 100644
--- a/src/code/language-support/c-net/client/graphql-client.md
+++ b/src/code/language-support/c-net/client/graphql-client.md
@@ -2,4 +2,7 @@
name: GraphQL.Client
description: A GraphQL Client for .NET.
github: graphql-dotnet/graphql-client
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/c-net/client/graphql-net-client.md b/src/code/language-support/c-net/client/graphql-net-client.md
index 3d230cd558..6919ae3d3b 100644
--- a/src/code/language-support/c-net/client/graphql-net-client.md
+++ b/src/code/language-support/c-net/client/graphql-net-client.md
@@ -2,4 +2,7 @@
name: graphql-net-client
description: Basic example GraphQL client for .NET.
github: bkniffler/graphql-net-client
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/c-net/client/linq2graphql.md b/src/code/language-support/c-net/client/linq2graphql.md
index b63319765c..b5283dd9b4 100644
--- a/src/code/language-support/c-net/client/linq2graphql.md
+++ b/src/code/language-support/c-net/client/linq2graphql.md
@@ -3,6 +3,9 @@ name: Linq2GraphQL
description: A straightforward Linq to GraphQL Client
url: https://linq2graphql.com
github: linq2graphql/linq2graphql.client
+tags:
+ - tools-and-libraries
+ - frontend
---
Linq2GraphQL generates C# classes from the GraphQL schema and and togheter with the nuget package Linq2GraphQL.Client it makes it possible to query the server using Linq expressions.
diff --git a/src/code/language-support/c-net/client/sahb-graphqlclient.md b/src/code/language-support/c-net/client/sahb-graphqlclient.md
index bc6eee69db..a0f7598713 100644
--- a/src/code/language-support/c-net/client/sahb-graphqlclient.md
+++ b/src/code/language-support/c-net/client/sahb-graphqlclient.md
@@ -2,4 +2,7 @@
name: SAHB.GraphQLClient
description: GraphQL client which supports generating queries from C# classes
github: sahb1239/SAHB.GraphQLClient
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/c-net/client/strawberry-shake.md b/src/code/language-support/c-net/client/strawberry-shake.md
index f18451aae7..8b725142c0 100644
--- a/src/code/language-support/c-net/client/strawberry-shake.md
+++ b/src/code/language-support/c-net/client/strawberry-shake.md
@@ -3,6 +3,9 @@ name: Strawberry Shake
description: Strawberry Shake is a open-source reactive GraphQL client for .NET
url: https://chillicream.com/docs/strawberryshake/
github: ChilliCream/hotchocolate
+tags:
+ - tools-and-libraries
+ - frontend
---
Strawberry Shake removes the complexity of state management and lets you interact with local and remote data through GraphQL.
diff --git a/src/code/language-support/c-net/client/zeroql.md b/src/code/language-support/c-net/client/zeroql.md
index 2a2de0a388..1b834d9a52 100644
--- a/src/code/language-support/c-net/client/zeroql.md
+++ b/src/code/language-support/c-net/client/zeroql.md
@@ -2,6 +2,9 @@
name: ZeroQL
description: ZeroQL is a open-source GraphQL client for C#
github: byme8/ZeroQL
+tags:
+ - tools-and-libraries
+ - frontend
---
The ZeroQL is a high-performance C#-friendly GraphQL client. It supports Linq-like syntax, and doesn't require Reflection.Emit or expressions.
diff --git a/src/code/language-support/c-net/server/entity-graphql.md b/src/code/language-support/c-net/server/entity-graphql.md
index b54cfa6c71..bcc432d3e9 100644
--- a/src/code/language-support/c-net/server/entity-graphql.md
+++ b/src/code/language-support/c-net/server/entity-graphql.md
@@ -3,6 +3,9 @@ name: Entity GraphQL
description: A GraphQL library for .NET Core. Easily expose you data model as a GraphQL API or bring together multiple data sources into a single GraphQL schema.
url: https://entitygraphql.github.io
github: EntityGraphQL/EntityGraphQL
+tags:
+ - tools-and-libraries
+ - backend
---
```csharp
diff --git a/src/code/language-support/c-net/server/graphql-dotnet.md b/src/code/language-support/c-net/server/graphql-dotnet.md
index c55ba4cbb5..fe64c67169 100644
--- a/src/code/language-support/c-net/server/graphql-dotnet.md
+++ b/src/code/language-support/c-net/server/graphql-dotnet.md
@@ -2,6 +2,9 @@
name: graphql-dotnet
description: GraphQL for .NET
github: graphql-dotnet/graphql-dotnet
+tags:
+ - tools-and-libraries
+ - backend
---
```csharp
diff --git a/src/code/language-support/c-net/server/graphql-net.md b/src/code/language-support/c-net/server/graphql-net.md
index 42c90fdeaa..9e591f91e1 100644
--- a/src/code/language-support/c-net/server/graphql-net.md
+++ b/src/code/language-support/c-net/server/graphql-net.md
@@ -2,4 +2,7 @@
name: graphql-net
description: Convert GraphQL to IQueryable
github: chkimes/graphql-net
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/c-net/server/hot-chocolate.md b/src/code/language-support/c-net/server/hot-chocolate.md
index 2b9704ad33..78ee422e79 100644
--- a/src/code/language-support/c-net/server/hot-chocolate.md
+++ b/src/code/language-support/c-net/server/hot-chocolate.md
@@ -3,6 +3,9 @@ name: Hot Chocolate
description: Hot Chocolate is an open-source GraphQL Server for .NET
url: https://chillicream.com/docs/hotchocolate/
github: ChilliCream/hotchocolate
+tags:
+ - tools-and-libraries
+ - backend
---
Hot Chocolate takes the complexity away from building a fully-fledged GraphQL server and lets you focus on delivering the next big thing.
diff --git a/src/code/language-support/c-net/server/ngraphql.md b/src/code/language-support/c-net/server/ngraphql.md
index bbe2bf5fd0..a4ba6d9196 100644
--- a/src/code/language-support/c-net/server/ngraphql.md
+++ b/src/code/language-support/c-net/server/ngraphql.md
@@ -2,4 +2,7 @@
name: NGraphQL
description: A set of packages for implementing high-performant GraphQL servers in .NET. Faithful implementation of official 2018 Specification. Features batched execution support (aka Data Loader); support for custom scalars; HTTP server based on ASP.NET Core; parsed query cache; modular API construction (equivalent of schema stiching); full introspection support; runtime metrics and quotas.
github: rivantsov/ngraphql
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/clojure/client/regraph.md b/src/code/language-support/clojure/client/regraph.md
index c6cc4b3936..c2c2b4248b 100644
--- a/src/code/language-support/clojure/client/regraph.md
+++ b/src/code/language-support/clojure/client/regraph.md
@@ -2,4 +2,7 @@
name: regraph
description: A GraphQL client implemented in Clojurescript with support for websockets.
github: oliyh/re-graph
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/clojure/server/alumbra.md b/src/code/language-support/clojure/server/alumbra.md
index 3509371d69..c05834055a 100644
--- a/src/code/language-support/clojure/server/alumbra.md
+++ b/src/code/language-support/clojure/server/alumbra.md
@@ -2,6 +2,9 @@
name: alumbra
description: A set of reusable GraphQL components for Clojure conforming to the data structures given in [alumbra.spec](https://github.com/alumbra/alumbra.spec).
github: alumbra/alumbra
+tags:
+ - tools-and-libraries
+ - backend
---
```clojure
diff --git a/src/code/language-support/clojure/server/graphql-clj.md b/src/code/language-support/clojure/server/graphql-clj.md
index 3f1eb595c4..7ec0f9047e 100644
--- a/src/code/language-support/clojure/server/graphql-clj.md
+++ b/src/code/language-support/clojure/server/graphql-clj.md
@@ -2,6 +2,9 @@
name: graphql-clj
description: A Clojure library that provides a GraphQL implementation.
github: tendant/graphql-clj
+tags:
+ - tools-and-libraries
+ - backend
---
Code that executes a hello world GraphQL query with `graphql-clj`:
diff --git a/src/code/language-support/clojure/server/lacinia.md b/src/code/language-support/clojure/server/lacinia.md
index a31a541239..2c5ec1f20b 100644
--- a/src/code/language-support/clojure/server/lacinia.md
+++ b/src/code/language-support/clojure/server/lacinia.md
@@ -2,4 +2,7 @@
name: lacinia
description: A full implementation of the GraphQL specification that aims to maintain external compliance with the specification.
github: walmartlabs/lacinia
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/d/server/graphqld.md b/src/code/language-support/d/server/graphqld.md
index b674835879..17b31d6c9f 100644
--- a/src/code/language-support/d/server/graphqld.md
+++ b/src/code/language-support/d/server/graphqld.md
@@ -2,4 +2,7 @@
name: graphqld
description: A GraphQL implementation for the D Programming Language.
github: burner/graphqld
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/elixir/client/common-graphql-client.md b/src/code/language-support/elixir/client/common-graphql-client.md
index 6aa7e8317f..c0a81450db 100644
--- a/src/code/language-support/elixir/client/common-graphql-client.md
+++ b/src/code/language-support/elixir/client/common-graphql-client.md
@@ -2,4 +2,7 @@
name: common_graphql_client
description: Elixir GraphQL Client with HTTP and WebSocket support
github: annkissam/common_graphql_client
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/elixir/client/neuron.md b/src/code/language-support/elixir/client/neuron.md
index d48cdbf149..ee9f96772a 100644
--- a/src/code/language-support/elixir/client/neuron.md
+++ b/src/code/language-support/elixir/client/neuron.md
@@ -2,4 +2,7 @@
name: Neuron
description: A GraphQL client for Elixir
github: uesteibar/neuron
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/elixir/server/absinthe.md b/src/code/language-support/elixir/server/absinthe.md
index f840056878..ea75e09bd8 100644
--- a/src/code/language-support/elixir/server/absinthe.md
+++ b/src/code/language-support/elixir/server/absinthe.md
@@ -2,4 +2,7 @@
name: absinthe
description: GraphQL implementation for Elixir.
github: absinthe-graphql/absinthe
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/elixir/server/graphql-elixir.md b/src/code/language-support/elixir/server/graphql-elixir.md
index 84f40c4bff..8d71d3b753 100644
--- a/src/code/language-support/elixir/server/graphql-elixir.md
+++ b/src/code/language-support/elixir/server/graphql-elixir.md
@@ -2,4 +2,7 @@
name: graphql-elixir
description: An Elixir implementation of Facebook's GraphQL.
github: graphql-elixir/graphql
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/elm/client/dillonkearns-elm-graphql.md b/src/code/language-support/elm/client/dillonkearns-elm-graphql.md
index 25e0a910cf..7a39d9da20 100644
--- a/src/code/language-support/elm/client/dillonkearns-elm-graphql.md
+++ b/src/code/language-support/elm/client/dillonkearns-elm-graphql.md
@@ -2,4 +2,7 @@
name: dillonkearns/elm-graphql
description: Library and command-line code generator to create type-safe Elm code for a GraphQL endpoint.
github: dillonkearns/elm-graphql
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/erlang/server/graphql-erlang.md b/src/code/language-support/erlang/server/graphql-erlang.md
index abc81a4245..a985c43eed 100644
--- a/src/code/language-support/erlang/server/graphql-erlang.md
+++ b/src/code/language-support/erlang/server/graphql-erlang.md
@@ -2,4 +2,7 @@
name: graphql-erlang
description: GraphQL implementation in Erlang.
github: jlouis/graphql-erlang
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/flutter/client/ferry.md b/src/code/language-support/flutter/client/ferry.md
index f821eb1a4a..a9106f1428 100644
--- a/src/code/language-support/flutter/client/ferry.md
+++ b/src/code/language-support/flutter/client/ferry.md
@@ -3,4 +3,7 @@ name: Ferry
description: Ferry is a simple, powerful GraphQL Client for Flutter and Dart.
url: https://ferrygraphql.com/
github: gql-dart/ferry
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/flutter/client/graphql.md b/src/code/language-support/flutter/client/graphql.md
index b3df96a6c7..f9c382ed63 100644
--- a/src/code/language-support/flutter/client/graphql.md
+++ b/src/code/language-support/flutter/client/graphql.md
@@ -2,4 +2,7 @@
name: graphql
description: A GraphQL client implementation in Flutter.
github: zino-app/graphql-flutter
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/go/client/genqlient.md b/src/code/language-support/go/client/genqlient.md
index ad115ef42c..666b05d6ed 100644
--- a/src/code/language-support/go/client/genqlient.md
+++ b/src/code/language-support/go/client/genqlient.md
@@ -2,6 +2,9 @@
name: genqlient
description: A truly type-safe Go GraphQL client.
github: Khan/genqlient
+tags:
+ - tools-and-libraries
+ - frontend
---
genqlient is a Go library to easily generate type-safe code to query a GraphQL API. It takes advantage of the fact that both GraphQL and Go are typed languages to ensure at compile-time that your code is making a valid GraphQL query and using the result correctly, all with a minimum of boilerplate.
diff --git a/src/code/language-support/go/client/go-graphql-client.md b/src/code/language-support/go/client/go-graphql-client.md
index 5c97642c12..8af6b9d0c7 100644
--- a/src/code/language-support/go/client/go-graphql-client.md
+++ b/src/code/language-support/go/client/go-graphql-client.md
@@ -2,4 +2,7 @@
name: go-graphql-client
description: A GraphQL Go client with Mutation, Query and Subscription support.
github: hasura/go-graphql-client
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/go/client/graphql.md b/src/code/language-support/go/client/graphql.md
index 8cef435ce6..2fcbc85fce 100644
--- a/src/code/language-support/go/client/graphql.md
+++ b/src/code/language-support/go/client/graphql.md
@@ -2,4 +2,7 @@
name: graphql
description: A GraphQL client implementation in Go.
github: shurcooL/graphql
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/go/client/machinebox-graphql.md b/src/code/language-support/go/client/machinebox-graphql.md
index 0fa6615bda..7bf1e86f9a 100644
--- a/src/code/language-support/go/client/machinebox-graphql.md
+++ b/src/code/language-support/go/client/machinebox-graphql.md
@@ -2,4 +2,7 @@
name: machinebox/graphql
description: An elegant low-level HTTP client for GraphQL.
github: machinebox/graphql
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/go/server/99designs-gqlgen.md b/src/code/language-support/go/server/99designs-gqlgen.md
index 39f99519e8..2211406d9c 100644
--- a/src/code/language-support/go/server/99designs-gqlgen.md
+++ b/src/code/language-support/go/server/99designs-gqlgen.md
@@ -2,4 +2,8 @@
name: 99designs/gqlgen
description: Go generate based graphql server library.
github: 99designs/gqlgen
+tags:
+ - tools-and-libraries
+ - backend
+ - backend
---
diff --git a/src/code/language-support/go/server/andrewwphillips-eggql.md b/src/code/language-support/go/server/andrewwphillips-eggql.md
index 02f3903f96..8b9c5b4cca 100644
--- a/src/code/language-support/go/server/andrewwphillips-eggql.md
+++ b/src/code/language-support/go/server/andrewwphillips-eggql.md
@@ -2,6 +2,9 @@
name: EGGQL
description: Easy to use, complete Go implementation of GraphQL. Simple and schema-less.
github: andrewwphillips/eggql
+tags:
+ - tools-and-libraries
+ - backend
---
The purpose of Eggql is to make it as simple as possible to create a GraphQL server. You don't need to create GraphQL schema (though you can view the schema that is created if interested). It is currently in beta release but is a complete implementation of a GraphQL server apart from subscriptions.
diff --git a/src/code/language-support/go/server/appointy-jaal.md b/src/code/language-support/go/server/appointy-jaal.md
index 1d6a153c94..6e9f0877d7 100644
--- a/src/code/language-support/go/server/appointy-jaal.md
+++ b/src/code/language-support/go/server/appointy-jaal.md
@@ -2,4 +2,7 @@
name: appointy/jaal
description: Develop spec compliant GraphQL servers in Go.
github: appointy/jaal
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/go/server/graph-gophers-graphql-go.md b/src/code/language-support/go/server/graph-gophers-graphql-go.md
index d3b37e25c7..1d4405986e 100644
--- a/src/code/language-support/go/server/graph-gophers-graphql-go.md
+++ b/src/code/language-support/go/server/graph-gophers-graphql-go.md
@@ -2,4 +2,7 @@
name: graph-gophers/graphql-go
description: GraphQL server with a focus on ease of use.
github: graph-gophers/graphql-go
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/go/server/graphql-go.md b/src/code/language-support/go/server/graphql-go.md
index f322d7c2b2..a1dec63694 100644
--- a/src/code/language-support/go/server/graphql-go.md
+++ b/src/code/language-support/go/server/graphql-go.md
@@ -2,4 +2,7 @@
name: graphql-go
description: An implementation of GraphQL for Go / Golang.
github: graphql-go/graphql
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/go/server/graphql-relay-go.md b/src/code/language-support/go/server/graphql-relay-go.md
index 3f00006580..93c859e566 100644
--- a/src/code/language-support/go/server/graphql-relay-go.md
+++ b/src/code/language-support/go/server/graphql-relay-go.md
@@ -2,4 +2,7 @@
name: graphql-relay-go
description: A Go/Golang library to help construct a graphql-go server supporting react-relay.
github: graphql-go/relay
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/go/server/samsarahq-thunder.md b/src/code/language-support/go/server/samsarahq-thunder.md
index 56ccc1e6f7..7ef290566a 100644
--- a/src/code/language-support/go/server/samsarahq-thunder.md
+++ b/src/code/language-support/go/server/samsarahq-thunder.md
@@ -2,4 +2,7 @@
name: samsarahq/thunder
description: A GraphQL implementation with easy schema building, live queries, and batching.
github: samsarahq/thunder
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/go/server/wundergraph-graphql-go-tools.md b/src/code/language-support/go/server/wundergraph-graphql-go-tools.md
index fcea03ca58..a389a263ce 100644
--- a/src/code/language-support/go/server/wundergraph-graphql-go-tools.md
+++ b/src/code/language-support/go/server/wundergraph-graphql-go-tools.md
@@ -2,6 +2,9 @@
name: graphql-go-tools
description: A collection of tools for building GraphQL Servers, Gateways, Proxy Servers and Middleware in Go.
github: wundergraph/graphql-go-tools
+tags:
+ - tools-and-libraries
+ - backend
---
graphql-go-tools implements all basic blocks for building GraphQL Servers, Gateways and Proxy Servers.
diff --git a/src/code/language-support/go/tools/graphjin.md b/src/code/language-support/go/tools/graphjin.md
index c7e091c922..1810b3e1d9 100644
--- a/src/code/language-support/go/tools/graphjin.md
+++ b/src/code/language-support/go/tools/graphjin.md
@@ -2,4 +2,7 @@
name: graphjin
description: An instant GraphQL to SQL compiler. Use as a standalone service or a Go library. Formerly super-graph.
github: dosco/graphjin
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/groovy/server/gorm-graphql.md b/src/code/language-support/groovy/server/gorm-graphql.md
index 9c6ba9c890..dd784cc9a8 100644
--- a/src/code/language-support/groovy/server/gorm-graphql.md
+++ b/src/code/language-support/groovy/server/gorm-graphql.md
@@ -3,6 +3,9 @@ name: gorm-graphql
description: An automatic GraphQL schema generator for GORM
url: https://grails.github.io/gorm-graphql/latest/guide/index.html
github: grails/gorm-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
**Core Library** - The GORM GraphQL library provides functionality to generate a GraphQL schema based on your GORM entities. In addition to mapping domain classes to a GraphQL schema, the core library also provides default implementations of "data fetchers" to query, update, and delete data through executions of the schema.
diff --git a/src/code/language-support/groovy/server/gql.md b/src/code/language-support/groovy/server/gql.md
index 7d1cfa2810..86ba5acf34 100644
--- a/src/code/language-support/groovy/server/gql.md
+++ b/src/code/language-support/groovy/server/gql.md
@@ -3,4 +3,7 @@ name: GQL
description: GQL is a Groove library for GraphQL
url: https://grooviter.github.io/gql/
github: grooviter/gql
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/haskell/client/morpheus-graphql-client.md b/src/code/language-support/haskell/client/morpheus-graphql-client.md
index a93783fab9..2a3ac3d97e 100644
--- a/src/code/language-support/haskell/client/morpheus-graphql-client.md
+++ b/src/code/language-support/haskell/client/morpheus-graphql-client.md
@@ -2,4 +2,7 @@
name: morpheus-graphql-client
description: A strongly-typed GraphQL client implementation in Haksell.
github: morpheusgraphql/morpheus-graphql
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/haskell/server/graphql-w-persistent.md b/src/code/language-support/haskell/server/graphql-w-persistent.md
index afea3da582..e02b2eda9f 100644
--- a/src/code/language-support/haskell/server/graphql-w-persistent.md
+++ b/src/code/language-support/haskell/server/graphql-w-persistent.md
@@ -3,6 +3,9 @@ name: graphql-w-persistent
description: Complete set of library tools to abstract relational database schemas with SQL, query with GraphQL, and return GraphQL results
url: https://hackage.haskell.org/package/graphql-w-persistent
github: jasonsychau/graphql-w-persistent
+tags:
+ - tools-and-libraries
+ - backend
---
One time setup: build schema, deploy as microservice or within server, query SQL database with GraphQL!
diff --git a/src/code/language-support/haskell/server/morpheus-graphql.md b/src/code/language-support/haskell/server/morpheus-graphql.md
index a2492b55d6..eee4704051 100644
--- a/src/code/language-support/haskell/server/morpheus-graphql.md
+++ b/src/code/language-support/haskell/server/morpheus-graphql.md
@@ -2,6 +2,9 @@
name: Morpheus GraphQL
description: A Haskell library for building GraphQL APIs.
github: morpheusgraphql/morpheus-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
Hello world example with `morpheus-graphql`:
diff --git a/src/code/language-support/haskell/server/mu-haskell.md b/src/code/language-support/haskell/server/mu-haskell.md
index 636f68d248..e22332e59c 100644
--- a/src/code/language-support/haskell/server/mu-haskell.md
+++ b/src/code/language-support/haskell/server/mu-haskell.md
@@ -3,6 +3,9 @@ name: Mu-Haskell with Mu-GraphQL
description: A Haskell library for building microservices (gRPC, HTTP) and GraphQL APIs.
url: https://higherkindness.io/mu-haskell/
github: higherkindness/mu-haskell
+tags:
+ - tools-and-libraries
+ - backend
---
Example implementation of a GraphQL server with type-level representation of the schema auto-generated:
diff --git a/src/code/language-support/java-kotlin-android/client/apollo-kotlin.md b/src/code/language-support/java-kotlin-android/client/apollo-kotlin.md
index bde28f030e..bd858014a0 100644
--- a/src/code/language-support/java-kotlin-android/client/apollo-kotlin.md
+++ b/src/code/language-support/java-kotlin-android/client/apollo-kotlin.md
@@ -2,6 +2,9 @@
name: Apollo Kotlin
description: A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
github: apollographql/apollo-kotlin
+tags:
+ - tools-and-libraries
+ - frontend
---
Apollo Kotlin (formerly known as Apollo Android) is a GraphQL client with support for Android, Java8+, iOS and Kotlin multiplatform in general. It features:
diff --git a/src/code/language-support/java-kotlin-android/client/graphql-kotlin.md b/src/code/language-support/java-kotlin-android/client/graphql-kotlin.md
index 2ad4be71ed..5594f2bb10 100644
--- a/src/code/language-support/java-kotlin-android/client/graphql-kotlin.md
+++ b/src/code/language-support/java-kotlin-android/client/graphql-kotlin.md
@@ -2,6 +2,9 @@
name: graphql-kotlin
description: A set of libraries for running GraphQL client and server in Kotlin.
github: ExpediaGroup/graphql-kotlin
+tags:
+ - tools-and-libraries
+ - frontend
---
GraphQL Kotlin provides a set of lightweight type-safe GraphQL HTTP clients. The library provides Ktor HTTP client and Spring WebClient based reference implementations as well as allows for custom implementations using other engines. Jackson and kotlinx-serialization type-safe data models are generated at build time by the provided Gradle and Maven plugins.
diff --git a/src/code/language-support/java-kotlin-android/client/nodes.md b/src/code/language-support/java-kotlin-android/client/nodes.md
index 8e345043c7..e94f5b3194 100644
--- a/src/code/language-support/java-kotlin-android/client/nodes.md
+++ b/src/code/language-support/java-kotlin-android/client/nodes.md
@@ -2,4 +2,7 @@
name: Nodes
description: A GraphQL JVM Client designed for constructing queries from standard model definitions. By American Express.
github: americanexpress/nodes
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/java-kotlin-android/server/graphql-calculator.md b/src/code/language-support/java-kotlin-android/server/graphql-calculator.md
index 48e2b79b14..c8d4d041c5 100644
--- a/src/code/language-support/java-kotlin-android/server/graphql-calculator.md
+++ b/src/code/language-support/java-kotlin-android/server/graphql-calculator.md
@@ -2,6 +2,9 @@
name: graphql-calculator
description: A lightweight graphql calculation engine.
github: graphql-calculator/graphql-calculator
+tags:
+ - tools-and-libraries
+ - backend
---
GraphQL Calculator is a lightweight graphql calculation engine,
diff --git a/src/code/language-support/java-kotlin-android/server/graphql-java-kickstart.md b/src/code/language-support/java-kotlin-android/server/graphql-java-kickstart.md
index bcae677e63..2d63950ad6 100644
--- a/src/code/language-support/java-kotlin-android/server/graphql-java-kickstart.md
+++ b/src/code/language-support/java-kotlin-android/server/graphql-java-kickstart.md
@@ -3,6 +3,9 @@ name: GraphQL Spring Boot
description: GraphQL Spring Boot from GraphQL Java Kickstart
url: https://www.graphql-java-kickstart.com/
github: graphql-java-kickstart/graphql-spring-boot
+tags:
+ - tools-and-libraries
+ - backend
---
The GraphQL Spring Boot turns any Spring Boot application into a GraphQL Server
diff --git a/src/code/language-support/java-kotlin-android/server/graphql-java.md b/src/code/language-support/java-kotlin-android/server/graphql-java.md
index fde0c33882..22746a9943 100644
--- a/src/code/language-support/java-kotlin-android/server/graphql-java.md
+++ b/src/code/language-support/java-kotlin-android/server/graphql-java.md
@@ -2,6 +2,9 @@
name: graphql-java
description: A Java library for building GraphQL APIs.
github: graphql-java/graphql-java
+tags:
+ - tools-and-libraries
+ - backend
---
See the [Getting Started tutorial](https://www.graphql-java.com/tutorials/getting-started-with-spring-boot) on the GraphQL Java website.
diff --git a/src/code/language-support/java-kotlin-android/server/graphql-kotlin.md b/src/code/language-support/java-kotlin-android/server/graphql-kotlin.md
index 5fcb04a3eb..e59f5e7a9d 100644
--- a/src/code/language-support/java-kotlin-android/server/graphql-kotlin.md
+++ b/src/code/language-support/java-kotlin-android/server/graphql-kotlin.md
@@ -2,6 +2,9 @@
name: graphql-kotlin
description: A set of libraries for running GraphQL client and server in Kotlin.
github: ExpediaGroup/graphql-kotlin
+tags:
+ - tools-and-libraries
+ - backend
---
GraphQL Kotlin follows a code first approach for generating your GraphQL schemas. Given the similarities between Kotlin and GraphQL, such as the ability to define nullable/non-nullable types, a schema can be generated from Kotlin code without any separate schema specification. To create a reactive GraphQL web server add following dependency to your Gradle build file:
diff --git a/src/code/language-support/java-kotlin-android/server/jimmer.md b/src/code/language-support/java-kotlin-android/server/jimmer.md
index 450b21691c..9beb9d3657 100644
--- a/src/code/language-support/java-kotlin-android/server/jimmer.md
+++ b/src/code/language-support/java-kotlin-android/server/jimmer.md
@@ -3,6 +3,9 @@ name: Jimmer
description: A revolutionary ORM framework for both java and kotlin, it also provides specialized API for rapid development of Spring GraphQL-based applications.
url: https://babyfish-ct.github.io/jimmer/
github: babyfish-ct/jimmer
+tags:
+ - tools-and-libraries
+ - backend
---
## Introduce
diff --git a/src/code/language-support/java-kotlin-android/server/kgraphql.md b/src/code/language-support/java-kotlin-android/server/kgraphql.md
index c664f126c9..6be577302b 100644
--- a/src/code/language-support/java-kotlin-android/server/kgraphql.md
+++ b/src/code/language-support/java-kotlin-android/server/kgraphql.md
@@ -3,6 +3,9 @@ name: KGraphQL
description: KGraphQL is a Kotlin implementation of GraphQL. It provides a rich DSL to set up the GraphQL schema.
url: https://kgraphql.io/
github: aPureBase/KGraphQL
+tags:
+ - tools-and-libraries
+ - backend
---
Here's an example on how to create a simple schema based on a kotlin data class plus a property resolver that gets applied onto your class.
diff --git a/src/code/language-support/java-kotlin-android/server/mp-graphql.md b/src/code/language-support/java-kotlin-android/server/mp-graphql.md
index ddf6faf3da..30a5d04181 100644
--- a/src/code/language-support/java-kotlin-android/server/mp-graphql.md
+++ b/src/code/language-support/java-kotlin-android/server/mp-graphql.md
@@ -2,6 +2,9 @@
name: MicroProfile GraphQL
description: MP GraphQL is a code-first specification for building GraphQL applications. It uses annotations and design patterns similar to JAX-RS to enable rapid development.
github: eclipse/microprofile-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
MicroProfile GraphQL is a GraphQL server and client specification for building GraphQL applications. It's unique
diff --git a/src/code/language-support/java-kotlin-android/server/netflix-dgs.md b/src/code/language-support/java-kotlin-android/server/netflix-dgs.md
index 9eb2dc4fb5..8acc0f3f4b 100644
--- a/src/code/language-support/java-kotlin-android/server/netflix-dgs.md
+++ b/src/code/language-support/java-kotlin-android/server/netflix-dgs.md
@@ -3,6 +3,9 @@ name: Domain Graph Service (DGS) Framework
description: The DGS Framework (Domain Graph Service) is a GraphQL server framework for Spring Boot, developed by Netflix.
url: https://netflix.github.io/dgs/
github: netflix/dgs-framework
+tags:
+ - tools-and-libraries
+ - backend
---
The DGS Framework (Domain Graph Service) is a GraphQL server framework for Spring Boot, developed by Netflix.
diff --git a/src/code/language-support/java-kotlin-android/server/spring-graphql.md b/src/code/language-support/java-kotlin-android/server/spring-graphql.md
index a239979514..bd9b037449 100644
--- a/src/code/language-support/java-kotlin-android/server/spring-graphql.md
+++ b/src/code/language-support/java-kotlin-android/server/spring-graphql.md
@@ -3,6 +3,9 @@ name: Spring for GraphQL
description: Spring for GraphQL provides support for Spring applications built on GraphQL Java.
url: https://spring.io/projects/spring-graphql
github: spring-projects/spring-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
Spring for GraphQL provides support for Spring applications built on
@@ -14,7 +17,7 @@ Spring for GraphQL provides support for Spring applications built on
Features:
-- Server handling of GraphQL requests over HTTP, WebSocket, and RSocket.
+- backend handling of GraphQL requests over HTTP, WebSocket, and RSocket.
- An annotation-based programming model where @Controller components use annotations to declare handler methods with flexible method signatures to fetch the data for specific GraphQL fields. For example:
```java
@@ -29,7 +32,7 @@ public class GreetingController {
}
```
-- Client support for executing GraphQL requests over HTTP, WebSocket, and RSocket.
+- frontend support for executing GraphQL requests over HTTP, WebSocket, and RSocket.
- Dedicated support for testing GraphQL requests over HTTP, WebSocket, and RSocket, as well as for testing directly against a server.
To get started, check the Spring GraphQL starter on https://start.spring.io and the
diff --git a/src/code/language-support/java-kotlin-android/tools/graphql-java-generator.md b/src/code/language-support/java-kotlin-android/tools/graphql-java-generator.md
index 1fa4e4dc20..4c1883e20d 100644
--- a/src/code/language-support/java-kotlin-android/tools/graphql-java-generator.md
+++ b/src/code/language-support/java-kotlin-android/tools/graphql-java-generator.md
@@ -3,6 +3,9 @@ name: GraphQL Java Generator
description: GraphQL Java Generator is a tool that generates Java code to speed up development for Client and Server of GraphQL APIs
url: https://github.com/graphql-java-generator
github: graphql-java-generator/graphql-gradle-plugin-project
+tags:
+ - tools-and-libraries
+ - tools
---
- GraphQL Java client: it generates the Java classes that call the GraphQL endpoint, and the POJO that will contain the data returned by the server.
diff --git a/src/code/language-support/javascript/client/apollo-client.md b/src/code/language-support/javascript/client/apollo-client.md
index 3d2a1193b1..6187bd6828 100644
--- a/src/code/language-support/javascript/client/apollo-client.md
+++ b/src/code/language-support/javascript/client/apollo-client.md
@@ -4,4 +4,7 @@ description: A powerful JavaScript GraphQL client, designed to work well with Re
url: http://apollographql.com/client/
github: apollographql/apollo-client
npm: "@apollo/client"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/aws-amplify.md b/src/code/language-support/javascript/client/aws-amplify.md
index cda313166a..33906801ba 100644
--- a/src/code/language-support/javascript/client/aws-amplify.md
+++ b/src/code/language-support/javascript/client/aws-amplify.md
@@ -4,4 +4,7 @@ description: A JavaScript library for application development using cloud servic
url: https://docs.amplify.aws/
github: aws-amplify/amplify-js
npm: "aws-amplify"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/gq-loader.md b/src/code/language-support/javascript/client/gq-loader.md
index 4bc7136356..caf12ad267 100644
--- a/src/code/language-support/javascript/client/gq-loader.md
+++ b/src/code/language-support/javascript/client/gq-loader.md
@@ -3,4 +3,7 @@ name: gq-loader
description: A simple JavaScript GraphQL client,Let the *.gql file be used as a module through webpack loader.
github: Houfeng/gq-loader
npm: "gq-loader"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/gqty.md b/src/code/language-support/javascript/client/gqty.md
index ff09c55474..6e98ece6fd 100644
--- a/src/code/language-support/javascript/client/gqty.md
+++ b/src/code/language-support/javascript/client/gqty.md
@@ -4,6 +4,9 @@ description: The No-GraphQL client for TypeScript.
url: http://gqty.dev/
github: gqty-dev/gqty
npm: "gqty"
+tags:
+ - tools-and-libraries
+ - frontend
---
GQty is a query builder, a query fetcher and a cache manager solution all-in-one.
diff --git a/src/code/language-support/javascript/client/grafoo.md b/src/code/language-support/javascript/client/grafoo.md
index 23b30d7971..0002fe7b3a 100644
--- a/src/code/language-support/javascript/client/grafoo.md
+++ b/src/code/language-support/javascript/client/grafoo.md
@@ -3,4 +3,7 @@ name: Grafoo
description: An all purpose GraphQL client with view layer integrations for multiple frameworks in just 1.6kb.
github: grafoojs/grafoo
npm: "@grafoo/core"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/graphql-box.md b/src/code/language-support/javascript/client/graphql-box.md
index b940bf6c1e..4d1fa90075 100644
--- a/src/code/language-support/javascript/client/graphql-box.md
+++ b/src/code/language-support/javascript/client/graphql-box.md
@@ -3,6 +3,9 @@ name: GraphQLBox client
description: An extensible GraphQL client with modules for react, caching, request parsing, web workers, websockets and more...
github: badbatch/graphql-box
npm: "@graphql-box/client"
+tags:
+ - tools-and-libraries
+ - frontend
---
The example below installs and initializes the GraphQLBox client with a persisted cache and debugging enabled.
diff --git a/src/code/language-support/javascript/client/graphql-hooks.md b/src/code/language-support/javascript/client/graphql-hooks.md
index eccfe2c72f..d092f140fc 100644
--- a/src/code/language-support/javascript/client/graphql-hooks.md
+++ b/src/code/language-support/javascript/client/graphql-hooks.md
@@ -3,6 +3,9 @@ name: graphql-hooks
description: Minimal React hooks-first GraphQL client with a tiny bundle, SSR support and caching
github: nearform/graphql-hooks
npm: graphql-hooks
+tags:
+ - tools-and-libraries
+ - frontend
---
- 🥇 First-class hooks API
diff --git a/src/code/language-support/javascript/client/graphql-http.md b/src/code/language-support/javascript/client/graphql-http.md
index 6f57b0a934..713687484d 100644
--- a/src/code/language-support/javascript/client/graphql-http.md
+++ b/src/code/language-support/javascript/client/graphql-http.md
@@ -3,4 +3,7 @@ name: GraphQL-HTTP
description: Simple, pluggable, zero-dependency, GraphQL over HTTP spec compliant server, client and audit suite.
github: graphql/graphql-http
npm: graphql-http
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/graphql-request.md b/src/code/language-support/javascript/client/graphql-request.md
index 27ae9b4ebe..369247dc38 100644
--- a/src/code/language-support/javascript/client/graphql-request.md
+++ b/src/code/language-support/javascript/client/graphql-request.md
@@ -3,4 +3,7 @@ name: GraphQL Request
description: A simple and flexible JavaScript GraphQL client that works in all JavaScript environments (the browser, Node.js, and React Native) - basically a lightweight wrapper around `fetch`.
github: jasonkuhrt/graphql-request
npm: "graphql-request"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/graphql-sse.md b/src/code/language-support/javascript/client/graphql-sse.md
index 8c2502d60c..4c3586b6b1 100644
--- a/src/code/language-support/javascript/client/graphql-sse.md
+++ b/src/code/language-support/javascript/client/graphql-sse.md
@@ -3,4 +3,7 @@ name: GraphQL-SSE
description: Zero-dependency, HTTP/1 safe, simple, GraphQL over Server-Sent Events Protocol server and client.
github: enisdenjo/graphql-sse
npm: "graphql-sse"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/graphql-ts-client.md b/src/code/language-support/javascript/client/graphql-ts-client.md
index 31627bcbf7..4ccc92d69f 100644
--- a/src/code/language-support/javascript/client/graphql-ts-client.md
+++ b/src/code/language-support/javascript/client/graphql-ts-client.md
@@ -3,4 +3,7 @@ name: graphql-ts-client
description: GraphQL client for TypeScript, automatically infers the type of the returned data according to the strongly typed query request
github: babyfish-ct/graphql-ts-client
npm: "graphql-ts-client-api"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/graphql-ws.md b/src/code/language-support/javascript/client/graphql-ws.md
index 4c6fa1303b..6b149f5cd6 100644
--- a/src/code/language-support/javascript/client/graphql-ws.md
+++ b/src/code/language-support/javascript/client/graphql-ws.md
@@ -3,4 +3,7 @@ name: GraphQL-WS
description: Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client.
github: enisdenjo/graphql-ws
npm: "graphql-ws"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/graphqurl.md b/src/code/language-support/javascript/client/graphqurl.md
index ee8eaf7009..74902e1572 100644
--- a/src/code/language-support/javascript/client/graphqurl.md
+++ b/src/code/language-support/javascript/client/graphqurl.md
@@ -3,4 +3,7 @@ name: graphqurl
description: curl for GraphQL with autocomplete, subscriptions and GraphiQL. Also a dead-simple universal javascript GraphQL client.
github: hasura/graphqurl
npm: "graphqurl"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/lokka.md b/src/code/language-support/javascript/client/lokka.md
index 001c3d4137..c28b6cc6b8 100644
--- a/src/code/language-support/javascript/client/lokka.md
+++ b/src/code/language-support/javascript/client/lokka.md
@@ -3,4 +3,7 @@ name: Lokka
description: A simple JavaScript GraphQL client that works in all JavaScript environments (the browser, Node.js, and React Native).
github: kadirahq/lokka
npm: "lokka"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/nanogql.md b/src/code/language-support/javascript/client/nanogql.md
index 8a8288f147..4e321937f8 100644
--- a/src/code/language-support/javascript/client/nanogql.md
+++ b/src/code/language-support/javascript/client/nanogql.md
@@ -3,4 +3,7 @@ name: nanographql
description: Tiny GraphQL client library using template strings.
github: choojs/nanographql
npm: "nanographql"
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/javascript/client/relay.md b/src/code/language-support/javascript/client/relay.md
index 353c12052e..6b382e0f5b 100644
--- a/src/code/language-support/javascript/client/relay.md
+++ b/src/code/language-support/javascript/client/relay.md
@@ -4,6 +4,9 @@ description: Facebook's framework for building React applications that talk to a
url: https://facebook.github.io/relay/
github: facebook/relay
npm: "react-relay"
+tags:
+ - tools-and-libraries
+ - frontend
---
Relay is a JavaScript framework for building data-driven React applications.
diff --git a/src/code/language-support/javascript/client/urql.md b/src/code/language-support/javascript/client/urql.md
index 801836bea7..3fcec28ade 100644
--- a/src/code/language-support/javascript/client/urql.md
+++ b/src/code/language-support/javascript/client/urql.md
@@ -4,6 +4,9 @@ description: A highly customizable and versatile GraphQL client with which you a
url: https://formidable.com/open-source/urql/docs/
github: FormidableLabs/urql
npm: "@urql/core"
+tags:
+ - tools-and-libraries
+ - frontend
---
`urql` is a GraphQL client that exposes a set of helpers for several frameworks.
diff --git a/src/code/language-support/javascript/server/apollo-server.md b/src/code/language-support/javascript/server/apollo-server.md
index ac951b7f41..5328443d11 100644
--- a/src/code/language-support/javascript/server/apollo-server.md
+++ b/src/code/language-support/javascript/server/apollo-server.md
@@ -4,6 +4,9 @@ description: A GraphQL server from Apollo that works with any Node.js HTTP frame
url: https://www.apollographql.com/docs/apollo-server/
github: apollographql/apollo-server
npm: "@apollo/server"
+tags:
+ - tools-and-libraries
+ - backend
---
To run a hello world server with Apollo Server:
diff --git a/src/code/language-support/javascript/server/graphql-box.md b/src/code/language-support/javascript/server/graphql-box.md
index 07e4e529c6..45a8c93d6b 100644
--- a/src/code/language-support/javascript/server/graphql-box.md
+++ b/src/code/language-support/javascript/server/graphql-box.md
@@ -3,6 +3,9 @@ name: GraphQLBox server
description: An extensible GraphQL server with modules for caching, request parsing, debugging, subscriptions and more...
github: badbatch/graphql-box
npm: "@graphql-box/server"
+tags:
+ - tools-and-libraries
+ - backend
---
The example below installs and initializes the GraphQLBox server with a persisted cache and debugging enabled.
diff --git a/src/code/language-support/javascript/server/graphql-http.md b/src/code/language-support/javascript/server/graphql-http.md
index 119f829749..4d5e912e43 100644
--- a/src/code/language-support/javascript/server/graphql-http.md
+++ b/src/code/language-support/javascript/server/graphql-http.md
@@ -3,4 +3,7 @@ name: GraphQL-HTTP
description: Simple, pluggable, zero-dependency, GraphQL over HTTP spec compliant server, client and audit suite.
github: graphql/graphql-http
npm: "graphql-http"
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/javascript/server/graphql-js.md b/src/code/language-support/javascript/server/graphql-js.md
index 43225c9d4f..4e3c0c0a3a 100644
--- a/src/code/language-support/javascript/server/graphql-js.md
+++ b/src/code/language-support/javascript/server/graphql-js.md
@@ -4,6 +4,9 @@ description: The reference implementation of the GraphQL specification, designed
url: /graphql-js/
github: graphql/graphql-js
npm: "graphql"
+tags:
+ - tools-and-libraries
+ - backend
---
To run a `GraphQL.js` hello world script from the command line:
diff --git a/src/code/language-support/javascript/server/graphql-sse.md b/src/code/language-support/javascript/server/graphql-sse.md
index 8c2502d60c..168d6a1577 100644
--- a/src/code/language-support/javascript/server/graphql-sse.md
+++ b/src/code/language-support/javascript/server/graphql-sse.md
@@ -3,4 +3,7 @@ name: GraphQL-SSE
description: Zero-dependency, HTTP/1 safe, simple, GraphQL over Server-Sent Events Protocol server and client.
github: enisdenjo/graphql-sse
npm: "graphql-sse"
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/javascript/server/graphql-ws.md b/src/code/language-support/javascript/server/graphql-ws.md
index 4c6fa1303b..1b18b0c3b4 100644
--- a/src/code/language-support/javascript/server/graphql-ws.md
+++ b/src/code/language-support/javascript/server/graphql-ws.md
@@ -3,4 +3,7 @@ name: GraphQL-WS
description: Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client.
github: enisdenjo/graphql-ws
npm: "graphql-ws"
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/javascript/server/graphql-yoga.md b/src/code/language-support/javascript/server/graphql-yoga.md
index 4bf4269873..288687a74e 100644
--- a/src/code/language-support/javascript/server/graphql-yoga.md
+++ b/src/code/language-support/javascript/server/graphql-yoga.md
@@ -3,6 +3,9 @@ name: graphql-yoga
description: GraphQL Yoga is a batteries-included cross-platform GraphQL over HTTP spec-compliant GraphQL Server using Envelop and GraphQL Tools.
github: dotansimha/graphql-yoga
npm: "graphql-yoga"
+tags:
+ - tools-and-libraries
+ - backend
---
- Built around the Fetch API `Request` & `Response` objects
diff --git a/src/code/language-support/javascript/server/mercurius.md b/src/code/language-support/javascript/server/mercurius.md
index 4f80d59c0a..4652736df4 100644
--- a/src/code/language-support/javascript/server/mercurius.md
+++ b/src/code/language-support/javascript/server/mercurius.md
@@ -4,6 +4,9 @@ description: Mercurius is a flexible and extendible GraphQL adapter for Fastify,
url: https://mercurius.dev/
github: mercurius-js/mercurius
npm: "mercurius"
+tags:
+ - tools-and-libraries
+ - backend
---
To run an hello world script with `mercurius`:
diff --git a/src/code/language-support/javascript/server/pylon.md b/src/code/language-support/javascript/server/pylon.md
index 908cc1c104..c2ccbdd163 100644
--- a/src/code/language-support/javascript/server/pylon.md
+++ b/src/code/language-support/javascript/server/pylon.md
@@ -3,6 +3,9 @@ name: Pylon
description: A code-first framework for GraphQL API development, where your schema reflects your functionality. Run `npm create pylon@latest` to get started.
url: https://pylon.cronit.io
github: getcronit/pylon
+tags:
+ - tools-and-libraries
+ - backend
---
1. **Create**
diff --git a/src/code/language-support/javascript/tools/brangr.md b/src/code/language-support/javascript/tools/brangr.md
index 48c790e1d7..95ad85be77 100644
--- a/src/code/language-support/javascript/tools/brangr.md
+++ b/src/code/language-support/javascript/tools/brangr.md
@@ -2,6 +2,9 @@
name: Brangr
description: Browse Any Graph - A user-friendly viewer for any GraphQL service
github: networkimprov/brangr
+tags:
+ - tools-and-libraries
+ - tools
---
**Brangr - *Br*owse *An*y *Gr*aph**
diff --git a/src/code/language-support/javascript/tools/giraphql.md b/src/code/language-support/javascript/tools/giraphql.md
index f4f2c62c8b..3440ae83bf 100644
--- a/src/code/language-support/javascript/tools/giraphql.md
+++ b/src/code/language-support/javascript/tools/giraphql.md
@@ -4,6 +4,9 @@ description: A plugin based schema builder for creating code-first GraphQL schem
url: https://giraphql.com/
github: hayes/giraphql
npm: "@giraphql/core"
+tags:
+ - tools-and-libraries
+ - tools
---
GiraphQL makes writing type-safe schemas simple, and works without a code generator,
diff --git a/src/code/language-support/javascript/tools/graphiql.md b/src/code/language-support/javascript/tools/graphiql.md
index c253d56842..ae0c73a248 100644
--- a/src/code/language-support/javascript/tools/graphiql.md
+++ b/src/code/language-support/javascript/tools/graphiql.md
@@ -3,4 +3,7 @@ name: GraphiQL
description: An interactive in-browser GraphQL IDE.
github: graphql/graphiql
npm: "graphiql"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-cli.md b/src/code/language-support/javascript/tools/graphql-cli.md
index f5276a1bcd..41b49e136b 100644
--- a/src/code/language-support/javascript/tools/graphql-cli.md
+++ b/src/code/language-support/javascript/tools/graphql-cli.md
@@ -4,4 +4,7 @@ description: A command line tool for common GraphQL development workflows.
url: https://graphql-cli.com
github: Urigo/graphql-cli
npm: "graphql-cli"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-code-generator.md b/src/code/language-support/javascript/tools/graphql-code-generator.md
index 1ba0a96afb..2c415bbad4 100644
--- a/src/code/language-support/javascript/tools/graphql-code-generator.md
+++ b/src/code/language-support/javascript/tools/graphql-code-generator.md
@@ -4,4 +4,7 @@ description: GraphQL code generator with flexible support for custom plugins and
url: https://graphql-code-generator.com
github: dotansimha/graphql-code-generator
npm: "@graphql-codegen/cli"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-config.md b/src/code/language-support/javascript/tools/graphql-config.md
index 05fb937d2c..6458d0e587 100644
--- a/src/code/language-support/javascript/tools/graphql-config.md
+++ b/src/code/language-support/javascript/tools/graphql-config.md
@@ -4,4 +4,7 @@ description: One configuration for all your GraphQL tools (supported by most too
url: https://graphql-config.com
github: kamilkisiela/graphql-config
npm: "graphql-config"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-eslint.md b/src/code/language-support/javascript/tools/graphql-eslint.md
index 6c270048f6..39bd32dd47 100644
--- a/src/code/language-support/javascript/tools/graphql-eslint.md
+++ b/src/code/language-support/javascript/tools/graphql-eslint.md
@@ -3,4 +3,7 @@ name: GraphQL-ESLint
description: GraphQL-ESLint integrates GraphQL AST in the ESLint core (as a parser).
github: dimaMachina/graphql-eslint/
npm: "@graphql-eslint/eslint-plugin"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-http.md b/src/code/language-support/javascript/tools/graphql-http.md
index 119f829749..924a86799a 100644
--- a/src/code/language-support/javascript/tools/graphql-http.md
+++ b/src/code/language-support/javascript/tools/graphql-http.md
@@ -3,4 +3,7 @@ name: GraphQL-HTTP
description: Simple, pluggable, zero-dependency, GraphQL over HTTP spec compliant server, client and audit suite.
github: graphql/graphql-http
npm: "graphql-http"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-inspector.md b/src/code/language-support/javascript/tools/graphql-inspector.md
index 5a0ca86175..943e2515a3 100644
--- a/src/code/language-support/javascript/tools/graphql-inspector.md
+++ b/src/code/language-support/javascript/tools/graphql-inspector.md
@@ -4,4 +4,7 @@ description: Compare schemas, validate documents, find breaking changes, find si
url: https://graphql-inspector.com/
github: kamilkisiela/graphql-inspector
npm: "@graphql-inspector/cli"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-language-service.md b/src/code/language-support/javascript/tools/graphql-language-service.md
index 10c6154038..b405a1589b 100644
--- a/src/code/language-support/javascript/tools/graphql-language-service.md
+++ b/src/code/language-support/javascript/tools/graphql-language-service.md
@@ -3,4 +3,7 @@ name: GraphQL Language Service
description: An interface for building GraphQL language services for IDEs (diagnostics, autocomplete etc).
github: graphql/graphql-language-service
npm: "graphql-language-service"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-live-query.md b/src/code/language-support/javascript/tools/graphql-live-query.md
index e65733a09d..f3c11eabc8 100644
--- a/src/code/language-support/javascript/tools/graphql-live-query.md
+++ b/src/code/language-support/javascript/tools/graphql-live-query.md
@@ -3,4 +3,7 @@ name: GraphQL Live Query
description: Real-Time with GraphQL for any GraphQL schema or transport.
github: n1ru4l/graphql-live-query
npm: "@n1ru4l/graphql-live-query"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-mesh.md b/src/code/language-support/javascript/tools/graphql-mesh.md
index 323b5319be..c02fa06c2e 100644
--- a/src/code/language-support/javascript/tools/graphql-mesh.md
+++ b/src/code/language-support/javascript/tools/graphql-mesh.md
@@ -4,4 +4,7 @@ description: GraphQL Mesh allows you to use GraphQL query language to access dat
url: https://graphql-mesh.com
github: Urigo/graphql-mesh
npm: "@graphql-mesh/cli"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-middleware.md b/src/code/language-support/javascript/tools/graphql-middleware.md
index 4d678b90ac..3e1a20b1fe 100644
--- a/src/code/language-support/javascript/tools/graphql-middleware.md
+++ b/src/code/language-support/javascript/tools/graphql-middleware.md
@@ -3,6 +3,9 @@ name: GraphQL Middleware
description: Split up your GraphQL resolvers in middleware functions.
github: maticzav/graphql-middleware
npm: graphql-middleware
+tags:
+ - tools-and-libraries
+ - tools
---
GraphQL Middleware is a schema wrapper which allows you to manage additional functionality across multiple resolvers efficiently.
diff --git a/src/code/language-support/javascript/tools/graphql-modules.md b/src/code/language-support/javascript/tools/graphql-modules.md
index d0d6270e44..b2c90c2e31 100644
--- a/src/code/language-support/javascript/tools/graphql-modules.md
+++ b/src/code/language-support/javascript/tools/graphql-modules.md
@@ -4,4 +4,7 @@ description: GraphQL Modules lets you separate your backend implementation to sm
url: https://graphql-modules.com
github: Urigo/graphql-modules
npm: "graphql-modules"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-scalars.md b/src/code/language-support/javascript/tools/graphql-scalars.md
index 1d04567b86..dc49d1413b 100644
--- a/src/code/language-support/javascript/tools/graphql-scalars.md
+++ b/src/code/language-support/javascript/tools/graphql-scalars.md
@@ -3,4 +3,7 @@ name: GraphQL Scalars
description: A library of custom GraphQL scalar types for creating precise, type-safe GraphQL schemas.
github: Urigo/graphql-scalars
npm: "graphql-scalars"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/graphql-shield.md b/src/code/language-support/javascript/tools/graphql-shield.md
index ee89db16b2..606ba176c2 100644
--- a/src/code/language-support/javascript/tools/graphql-shield.md
+++ b/src/code/language-support/javascript/tools/graphql-shield.md
@@ -3,6 +3,9 @@ name: GraphQLShield
description: A GraphQL tool to ease the creation of permission layer.
github: maticzav/graphql-shield
npm: "graphql-shield"
+tags:
+ - tools-and-libraries
+ - tools
---
GraphQL Shield helps you create a permission layer for your application. Using an intuitive rule-API, you'll gain the power of the shield engine on every request and reduce the load time of every request with smart caching. This way you can make sure your application will remain quick, and no internal data will be exposed.
diff --git a/src/code/language-support/javascript/tools/graphql-tools.md b/src/code/language-support/javascript/tools/graphql-tools.md
index af2e896ec7..f59c74a6e4 100644
--- a/src/code/language-support/javascript/tools/graphql-tools.md
+++ b/src/code/language-support/javascript/tools/graphql-tools.md
@@ -4,4 +4,7 @@ description: A set of utils for faster development of GraphQL tools (Schema and
url: https://graphql-tools.com
github: ardatan/graphql-tools
npm: "graphql-tools"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/microfiber.md b/src/code/language-support/javascript/tools/microfiber.md
index 2e0e1ef897..5132d1d9bc 100644
--- a/src/code/language-support/javascript/tools/microfiber.md
+++ b/src/code/language-support/javascript/tools/microfiber.md
@@ -3,6 +3,9 @@ name: Microfiber
description: A library to query and manipulate GraphQL Introspection Query results.
github: anvilco/graphql-introspection-tools
npm: "microfiber"
+tags:
+ - tools-and-libraries
+ - tools
---
Microfiber is a JavaScript library that allows:
diff --git a/src/code/language-support/javascript/tools/postgraphile.md b/src/code/language-support/javascript/tools/postgraphile.md
index 2d25254918..20e5fe5ce4 100644
--- a/src/code/language-support/javascript/tools/postgraphile.md
+++ b/src/code/language-support/javascript/tools/postgraphile.md
@@ -4,4 +4,7 @@ description: builds a powerful, extensible and performant GraphQL API from a Pos
url: https://www.graphile.org/postgraphile
github: graphile/postgraphile
npm: "postgraphile"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/sofa.md b/src/code/language-support/javascript/tools/sofa.md
index 4be7ae4ef3..deb8688298 100644
--- a/src/code/language-support/javascript/tools/sofa.md
+++ b/src/code/language-support/javascript/tools/sofa.md
@@ -4,4 +4,7 @@ description: Generate REST API from your GraphQL API.
url: https://sofa-api.com/
github: Urigo/SOFA
npm: "sofa-api"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/language-support/javascript/tools/spectaql.md b/src/code/language-support/javascript/tools/spectaql.md
index a2475ccf0c..ebb29789b2 100644
--- a/src/code/language-support/javascript/tools/spectaql.md
+++ b/src/code/language-support/javascript/tools/spectaql.md
@@ -3,6 +3,9 @@ name: SpectaQL
description: SpectaQL generates static HTML documentation from a GraphQL schema.
github: anvilco/spectaql
npm: "spectaql"
+tags:
+ - tools-and-libraries
+ - tools
---
SpectaQL is a Node.js library that generates static documentation for a GraphQL schema using a variety of options:
diff --git a/src/code/language-support/julia/client/diana-jl.md b/src/code/language-support/julia/client/diana-jl.md
index e2c418a0a7..b551116334 100644
--- a/src/code/language-support/julia/client/diana-jl.md
+++ b/src/code/language-support/julia/client/diana-jl.md
@@ -2,4 +2,7 @@
name: Diana.jl
description: A Julia GraphQL server implementation.
github: neomatrixcode/Diana.jl
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/julia/client/graphqlclient-jl.md b/src/code/language-support/julia/client/graphqlclient-jl.md
index 3b1027b6ce..6705a83e00 100644
--- a/src/code/language-support/julia/client/graphqlclient-jl.md
+++ b/src/code/language-support/julia/client/graphqlclient-jl.md
@@ -2,6 +2,9 @@
name: GraphQLClient.jl
description: A Julia GraphQL client for seamless integration with a GraphQL server
github: DeloitteDigitalAPAC/GraphQLClient.jl
+tags:
+ - tools-and-libraries
+ - frontend
---
- **Querying**, **mutating** and **subscribing** without manual writing of query strings (unless you want to!)
diff --git a/src/code/language-support/ocaml-reason/server/ocaml-graphql-server.md b/src/code/language-support/ocaml-reason/server/ocaml-graphql-server.md
index 8c3ad6628b..415da69c89 100644
--- a/src/code/language-support/ocaml-reason/server/ocaml-graphql-server.md
+++ b/src/code/language-support/ocaml-reason/server/ocaml-graphql-server.md
@@ -2,4 +2,7 @@
name: ocaml-graphql-server
description: GraphQL server library for OCaml and Reason
github: andreas/ocaml-graphql-server
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/perl/server/graphql-perl.md b/src/code/language-support/perl/server/graphql-perl.md
index 74baad10a7..d8c7323026 100644
--- a/src/code/language-support/perl/server/graphql-perl.md
+++ b/src/code/language-support/perl/server/graphql-perl.md
@@ -2,6 +2,9 @@
name: graphql-perl
description: A Perl port of GraphQL reference implementation
github: graphql-perl/graphql-perl
+tags:
+ - tools-and-libraries
+ - backend
---
- [MetaCPAN documentation](https://metacpan.org/pod/GraphQL)
diff --git a/src/code/language-support/php/server/api-platform.md b/src/code/language-support/php/server/api-platform.md
index 533db54b6c..2549a6ffd0 100644
--- a/src/code/language-support/php/server/api-platform.md
+++ b/src/code/language-support/php/server/api-platform.md
@@ -3,6 +3,9 @@ name: API Platform
description: API Platform is a fully-featured, flexible and extensible API framework built on top of Symfony.
url: https://api-platform.com
github: api-platform/api-platform
+tags:
+ - tools-and-libraries
+ - backend
---
The following class is enough to create both a Relay-compatible GraphQL server and a hypermedia API supporting modern REST formats (JSON-LD, JSONAPI...):
diff --git a/src/code/language-support/php/server/gatographql.md b/src/code/language-support/php/server/gatographql.md
index 1fb71135fc..43f905c39f 100644
--- a/src/code/language-support/php/server/gatographql.md
+++ b/src/code/language-support/php/server/gatographql.md
@@ -3,4 +3,7 @@ name: Gato GraphQL
description: Interact with all your data in WordPress
url: https://gatographql.com
github: GatoGraphQL/GatoGraphQL
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/graphpinator.md b/src/code/language-support/php/server/graphpinator.md
index be2ad7948a..b5edb462b2 100644
--- a/src/code/language-support/php/server/graphpinator.md
+++ b/src/code/language-support/php/server/graphpinator.md
@@ -2,6 +2,9 @@
name: GraPHPinator
description: A GraphQL implementation for modern PHP. Includes features from latest draft, middleware directives and modules with extra functionality.
github: infinityloop-dev/graphpinator
+tags:
+ - tools-and-libraries
+ - backend
---
GraPHPinator is feature complete PHP implementation of GraphQL server. Its job is transformation of query string into resolved Json result for a given Schema.
diff --git a/src/code/language-support/php/server/graphql-attribute-schema.md b/src/code/language-support/php/server/graphql-attribute-schema.md
index f07fe4cfc1..049ebe50bb 100644
--- a/src/code/language-support/php/server/graphql-attribute-schema.md
+++ b/src/code/language-support/php/server/graphql-attribute-schema.md
@@ -3,6 +3,9 @@ name: graphql-attribute-schema
description: Easily build your GraphQL schema for webonyx/graphql-php using PHP attributes instead of large configuration arrays.
url: https://jerowork.github.io/graphql-attribute-schema
github: jerowork/graphql-attribute-schema
+tags:
+ - tools-and-libraries
+ - backend
---
Easily build your GraphQL schema for `webonyx/graphql-php` using PHP attributes instead of large configuration arrays.
diff --git a/src/code/language-support/php/server/graphql-php.md b/src/code/language-support/php/server/graphql-php.md
index 110b7adaca..b4b077df79 100644
--- a/src/code/language-support/php/server/graphql-php.md
+++ b/src/code/language-support/php/server/graphql-php.md
@@ -2,4 +2,7 @@
name: graphql-php
description: A PHP port of GraphQL reference implementation
github: webonyx/graphql-php
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/graphql-relay-php.md b/src/code/language-support/php/server/graphql-relay-php.md
index f9180f9d96..7d504df9ed 100644
--- a/src/code/language-support/php/server/graphql-relay-php.md
+++ b/src/code/language-support/php/server/graphql-relay-php.md
@@ -2,4 +2,7 @@
name: graphql-relay-php
description: A library to help construct a graphql-php server supporting react-relay.
github: ivome/graphql-relay-php
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/graphqlbundle.md b/src/code/language-support/php/server/graphqlbundle.md
index 815c103447..55d33f6e34 100644
--- a/src/code/language-support/php/server/graphqlbundle.md
+++ b/src/code/language-support/php/server/graphqlbundle.md
@@ -2,4 +2,7 @@
name: GraphQLBundle
description: A GraphQL server for Symfony
github: overblog/GraphQLBundle
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/graphqlite.md b/src/code/language-support/php/server/graphqlite.md
index e52d94638b..14a5e64da0 100644
--- a/src/code/language-support/php/server/graphqlite.md
+++ b/src/code/language-support/php/server/graphqlite.md
@@ -3,6 +3,9 @@ name: GraphQLite
description: GraphQLite is a library that offers an annotations-based syntax for GraphQL schema definition.
url: https://graphqlite.thecodingmachine.io
github: thecodingmachine/graphqlite
+tags:
+ - tools-and-libraries
+ - backend
---
It is framework agnostic with bindings available for Symfony and Laravel.
diff --git a/src/code/language-support/php/server/lighthouse.md b/src/code/language-support/php/server/lighthouse.md
index 4c2918d9cc..822893058d 100644
--- a/src/code/language-support/php/server/lighthouse.md
+++ b/src/code/language-support/php/server/lighthouse.md
@@ -2,4 +2,7 @@
name: Lighthouse
description: A GraphQL server for Laravel
github: nuwave/lighthouse
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/railt.md b/src/code/language-support/php/server/railt.md
index 4cff5b4cce..f348535359 100644
--- a/src/code/language-support/php/server/railt.md
+++ b/src/code/language-support/php/server/railt.md
@@ -2,4 +2,7 @@
name: Railt
description: A PHP GraphQL Framework.
github: railt/railt
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/serge.md b/src/code/language-support/php/server/serge.md
index 109973bd2a..014c2b6b81 100644
--- a/src/code/language-support/php/server/serge.md
+++ b/src/code/language-support/php/server/serge.md
@@ -2,4 +2,7 @@
name: serge
description: Use GraphQL to define your Domain Model for CQRS/ES and let serge generate code to handle GraphQL requests.
github: kepawni/serge
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/php/server/siler.md b/src/code/language-support/php/server/siler.md
index 5abe714068..ab6a6f99f5 100644
--- a/src/code/language-support/php/server/siler.md
+++ b/src/code/language-support/php/server/siler.md
@@ -3,6 +3,9 @@ name: Siler
description: Siler is a PHP library powered with high-level abstractions to work with GraphQL.
url: https://siler.leocavalcante.com/graphql/
github: leocavalcante/siler
+tags:
+ - tools-and-libraries
+ - backend
---
To run a Siler hello world script:
diff --git a/src/code/language-support/php/server/wpgraphql.md b/src/code/language-support/php/server/wpgraphql.md
index f21fead7e3..50de3ba239 100644
--- a/src/code/language-support/php/server/wpgraphql.md
+++ b/src/code/language-support/php/server/wpgraphql.md
@@ -2,4 +2,7 @@
name: WPGraphQL
description: A free, open-source WordPress plugin that provides an extendable GraphQL schema and API for any WordPress site
github: wp-graphql/wp-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/python/client/ariadne-codegen.md b/src/code/language-support/python/client/ariadne-codegen.md
index 66c5b84c50..b5dbb9ffd1 100644
--- a/src/code/language-support/python/client/ariadne-codegen.md
+++ b/src/code/language-support/python/client/ariadne-codegen.md
@@ -2,6 +2,9 @@
name: Ariadne Codegen
description: Generate fully typed Python GraphQL client from any schema and queries.
github: mirumee/ariadne-codegen
+tags:
+ - tools-and-libraries
+ - frontend
---
Install Ariadne Codegen:
diff --git a/src/code/language-support/python/client/gql.md b/src/code/language-support/python/client/gql.md
index cd89499ef8..68c7e2f4b8 100644
--- a/src/code/language-support/python/client/gql.md
+++ b/src/code/language-support/python/client/gql.md
@@ -2,4 +2,7 @@
name: GQL
description: A GraphQL client in Python.
github: graphql-python/gql
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/python/client/graphql-query.md b/src/code/language-support/python/client/graphql-query.md
index ddf389f433..61418755c3 100644
--- a/src/code/language-support/python/client/graphql-query.md
+++ b/src/code/language-support/python/client/graphql-query.md
@@ -3,6 +3,9 @@ name: graphql-query
description: Complete GraphQL query string generation for python.
url: https://denisart.github.io/graphql-query/
github: denisart/graphql-query
+tags:
+ - tools-and-libraries
+ - frontend
---
**graphql_query** is complete GraphQL query string builder for python. With **graphql_query**
diff --git a/src/code/language-support/python/client/python-graphql-client.md b/src/code/language-support/python/client/python-graphql-client.md
index eb0c7979ef..92849e5e96 100644
--- a/src/code/language-support/python/client/python-graphql-client.md
+++ b/src/code/language-support/python/client/python-graphql-client.md
@@ -3,4 +3,7 @@ name: python-graphql-client
description: Simple GraphQL client for Python 2.7+.
url: https://github.com/prisma/python-graphql-client
github: prisma-labs/python-graphql-client
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/python/client/ql.md b/src/code/language-support/python/client/ql.md
index 0258220f66..50285179bf 100644
--- a/src/code/language-support/python/client/ql.md
+++ b/src/code/language-support/python/client/ql.md
@@ -3,6 +3,9 @@ name: ql
description: Non intrusive python GraphQL client wrapped around pydantic.
url: https://dsal3389.github.io/ql/
github: dsal3389/ql
+tags:
+ - tools-and-libraries
+ - frontend
---
GraphQL client library, wrapped around pydantic classes for type validation,
diff --git a/src/code/language-support/python/client/qlient.md b/src/code/language-support/python/client/qlient.md
index 2a51180331..6935343899 100644
--- a/src/code/language-support/python/client/qlient.md
+++ b/src/code/language-support/python/client/qlient.md
@@ -2,6 +2,9 @@
name: Qlient
description: A fast and modern graphql client designed with simplicity in mind.
github: qlient-org/python-qlient
+tags:
+ - tools-and-libraries
+ - frontend
---
Here's an example of a qlient hello world.
diff --git a/src/code/language-support/python/client/sgqlc.md b/src/code/language-support/python/client/sgqlc.md
index f15564301b..de4618b518 100644
--- a/src/code/language-support/python/client/sgqlc.md
+++ b/src/code/language-support/python/client/sgqlc.md
@@ -2,4 +2,7 @@
name: sgqlc
description: A simple Python GraphQL client. Supports generating code generation for types defined in a GraphQL schema.
github: profusion/sgqlc
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/python/server/ariadne.md b/src/code/language-support/python/server/ariadne.md
index 92e9654527..fdb87df056 100644
--- a/src/code/language-support/python/server/ariadne.md
+++ b/src/code/language-support/python/server/ariadne.md
@@ -3,6 +3,9 @@ name: Ariadne
description: Ariadne is a Python library for implementing GraphQL servers using schema-first approach. It supports both synchronous and asynchronous query execution, ships with batteries included for common GraphQL server problems like query cost validation or performance tracing and has simple API that is easy to extend or replace.
url: https://ariadnegraphql.org
github: mirumee/ariadne
+tags:
+ - tools-and-libraries
+ - backend
---
Ariadne can be installed with pip:
diff --git a/src/code/language-support/python/server/django-graphbox.md b/src/code/language-support/python/server/django-graphbox.md
index 0971f80fea..22101cec51 100644
--- a/src/code/language-support/python/server/django-graphbox.md
+++ b/src/code/language-support/python/server/django-graphbox.md
@@ -3,6 +3,9 @@ name: Django Graphbox
description: Package for easy building a GraphQL API with basic CRUD operations for Django models.
url: https://90horasporsemana.com/graphbox/
github: yefeza/django-graphbox
+tags:
+ - tools-and-libraries
+ - backend
---
A Quickstart for Django Graphbox:
diff --git a/src/code/language-support/python/server/graphene-django-cruddals.md b/src/code/language-support/python/server/graphene-django-cruddals.md
index 66a34c7071..eab1efa424 100644
--- a/src/code/language-support/python/server/graphene-django-cruddals.md
+++ b/src/code/language-support/python/server/graphene-django-cruddals.md
@@ -3,6 +3,9 @@ name: Graphene Django CRUDDALS
description: Turn your Django-models into a complete GraphQL API with all CRUD operations
url: https://graphene-django-cruddals.readthedocs.io/en/latest/
github: juanjcardona13/graphene_django_cruddals
+tags:
+ - tools-and-libraries
+ - backend
---
You can install the package with pip
diff --git a/src/code/language-support/python/server/graphene.md b/src/code/language-support/python/server/graphene.md
index 772aaabc70..818abb77eb 100644
--- a/src/code/language-support/python/server/graphene.md
+++ b/src/code/language-support/python/server/graphene.md
@@ -3,6 +3,9 @@ name: Graphene
description: A Python library for building GraphQL APIs.
url: http://graphene-python.org/
github: graphql-python/graphene
+tags:
+ - tools-and-libraries
+ - backend
---
To run a Graphene hello world script:
diff --git a/src/code/language-support/python/server/strawberry.md b/src/code/language-support/python/server/strawberry.md
index fa3f7e39eb..1f3769330c 100644
--- a/src/code/language-support/python/server/strawberry.md
+++ b/src/code/language-support/python/server/strawberry.md
@@ -3,6 +3,9 @@ name: Strawberry
description: Strawberry is a Python library for implementing code first GraphQL servers using modern Python features like type hints.
url: https://strawberry.rocks
github: strawberry-graphql/strawberry
+tags:
+ - tools-and-libraries
+ - backend
---
Here's an example of a Strawberry hello world, first install the library:
diff --git a/src/code/language-support/python/server/tartiflette.md b/src/code/language-support/python/server/tartiflette.md
index e01b4a3993..c8c997521c 100644
--- a/src/code/language-support/python/server/tartiflette.md
+++ b/src/code/language-support/python/server/tartiflette.md
@@ -3,6 +3,9 @@ name: Tartiflette
description: A Python 3.6+ _(asyncio)_ library for building GraphQL APIs.
url: https://tartiflette.io
github: tartiflette/tartiflette
+tags:
+ - tools-and-libraries
+ - backend
---
To run a tartiflette hello world script:
diff --git a/src/code/language-support/r/server/ghql.md b/src/code/language-support/r/server/ghql.md
index c5679f4829..e4e248a2fd 100644
--- a/src/code/language-support/r/server/ghql.md
+++ b/src/code/language-support/r/server/ghql.md
@@ -2,4 +2,7 @@
name: ghql
description: General purpose GraphQL R client
github: ropensci/ghql
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/ruby/server/agoo.md b/src/code/language-support/ruby/server/agoo.md
index 7b02a430a6..d04ffd30b2 100644
--- a/src/code/language-support/ruby/server/agoo.md
+++ b/src/code/language-support/ruby/server/agoo.md
@@ -3,6 +3,9 @@ name: Agoo
description: A high performance web server with support for GraphQL. Agoo strives for a simple, easy to use API for GraphQL.
github: ohler55/agoo
gem: agoo
+tags:
+ - tools-and-libraries
+ - backend
---
```ruby
diff --git a/src/code/language-support/ruby/server/graphql-ruby.md b/src/code/language-support/ruby/server/graphql-ruby.md
index d88eb5bf9b..c8d0a47449 100644
--- a/src/code/language-support/ruby/server/graphql-ruby.md
+++ b/src/code/language-support/ruby/server/graphql-ruby.md
@@ -3,6 +3,9 @@ name: graphql-ruby
description: A Ruby library for building GraphQL APIs.
github: rmosolgo/graphql-ruby
gem: graphql
+tags:
+ - tools-and-libraries
+ - backend
---
To run a hello world script with `graphql-ruby`:
diff --git a/src/code/language-support/ruby/server/rails-graphql.md b/src/code/language-support/ruby/server/rails-graphql.md
index 6adebdf042..5ca526c3c0 100644
--- a/src/code/language-support/ruby/server/rails-graphql.md
+++ b/src/code/language-support/ruby/server/rails-graphql.md
@@ -4,6 +4,9 @@ description: A Fresh new GraphQL server for Rails applications, with a focus on
url: https://www.rails-graphql.dev/
github: virtualshield/rails-graphql
gem: rails-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
```ruby
diff --git a/src/code/language-support/rust/client/cynic.md b/src/code/language-support/rust/client/cynic.md
index f1680b6945..543d310f4d 100644
--- a/src/code/language-support/rust/client/cynic.md
+++ b/src/code/language-support/rust/client/cynic.md
@@ -3,6 +3,9 @@ name: cynic
description: A bring your own types GraphQL client for Rust
url: https://cynic-rs.dev
github: obmarg/cynic
+tags:
+ - tools-and-libraries
+ - frontend
---
A client library for rust that generates queries from types you provide,
diff --git a/src/code/language-support/rust/client/gql_client.md b/src/code/language-support/rust/client/gql_client.md
index f0bcc85a34..35614ea004 100644
--- a/src/code/language-support/rust/client/gql_client.md
+++ b/src/code/language-support/rust/client/gql_client.md
@@ -2,6 +2,9 @@
name: gql_client
description: Minimal GraphQL client for Rust
github: arthurkhlghatyan/gql-client-rs
+tags:
+ - tools-and-libraries
+ - frontend
---
Usage example
diff --git a/src/code/language-support/rust/server/async-graphql.md b/src/code/language-support/rust/server/async-graphql.md
index 655bbfe34f..8072cbe61f 100644
--- a/src/code/language-support/rust/server/async-graphql.md
+++ b/src/code/language-support/rust/server/async-graphql.md
@@ -2,6 +2,9 @@
name: Async-graphql
description: Async-graphql is a high-performance server-side library that supports all GraphQL specifications.
github: async-graphql/async-graphql
+tags:
+ - tools-and-libraries
+ - backend
---
```rust
diff --git a/src/code/language-support/rust/server/graphql-rust-juniper.md b/src/code/language-support/rust/server/graphql-rust-juniper.md
index 8e68bd9bea..fa356e1573 100644
--- a/src/code/language-support/rust/server/graphql-rust-juniper.md
+++ b/src/code/language-support/rust/server/graphql-rust-juniper.md
@@ -2,4 +2,7 @@
name: graphql-rust/juniper
description: GraphQL server library for Rust
github: graphql-rust/juniper
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/scala/client/caliban.md b/src/code/language-support/scala/client/caliban.md
index 4ad957d629..32e11d9b8d 100644
--- a/src/code/language-support/scala/client/caliban.md
+++ b/src/code/language-support/scala/client/caliban.md
@@ -3,6 +3,9 @@ name: Caliban
description: Caliban is a functional library for building GraphQL servers and clients in Scala. It offers with client code generation and type-safe queries.
url: https://ghostdogpr.github.io/caliban/
github: ghostdogpr/caliban
+tags:
+ - tools-and-libraries
+ - frontend
---
An example of defining a GraphQL query and running it with `caliban`:
diff --git a/src/code/language-support/scala/server/caliban.md b/src/code/language-support/scala/server/caliban.md
index 404ccfb6c5..93a3659390 100644
--- a/src/code/language-support/scala/server/caliban.md
+++ b/src/code/language-support/scala/server/caliban.md
@@ -3,6 +3,9 @@ name: Caliban
description: Caliban is a functional library for building GraphQL servers and clients in Scala. It offers minimal boilerplate and excellent interoperability.
url: https://ghostdogpr.github.io/caliban/
github: ghostdogpr/caliban
+tags:
+ - tools-and-libraries
+ - backend
---
An example of a simple GraphQL schema and query with `caliban`:
diff --git a/src/code/language-support/scala/server/sangria.md b/src/code/language-support/scala/server/sangria.md
index 63a94527a9..b0f20d33f2 100644
--- a/src/code/language-support/scala/server/sangria.md
+++ b/src/code/language-support/scala/server/sangria.md
@@ -3,6 +3,9 @@ name: Sangria
description: A Scala GraphQL library that supports [Relay](https://facebook.github.io/relay/).
url: https://sangria-graphql.github.io/
github: sangria-graphql/sangria
+tags:
+ - tools-and-libraries
+ - backend
---
An example of a hello world GraphQL schema and query with `sangria`:
diff --git a/src/code/language-support/swift-objective-c-ios/client/apollo-ios.md b/src/code/language-support/swift-objective-c-ios/client/apollo-ios.md
index c000c73537..bb259a12d3 100644
--- a/src/code/language-support/swift-objective-c-ios/client/apollo-ios.md
+++ b/src/code/language-support/swift-objective-c-ios/client/apollo-ios.md
@@ -3,4 +3,7 @@ name: Apollo iOS
description: A GraphQL client for iOS that returns results as query-specific Swift types, and integrates with Xcode to show your Swift source and GraphQL side by side, with inline validation errors.
url: https://www.apollographql.com/docs/ios/
github: apollographql/apollo-ios
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/swift-objective-c-ios/client/graphaello.md b/src/code/language-support/swift-objective-c-ios/client/graphaello.md
index 63215a428e..4900991c29 100644
--- a/src/code/language-support/swift-objective-c-ios/client/graphaello.md
+++ b/src/code/language-support/swift-objective-c-ios/client/graphaello.md
@@ -2,4 +2,7 @@
name: Graphaello
description: A Tool for Writing Declarative, Type-Safe and Data-Driven Applications in SwiftUI using GraphQL and Apollo
github: nerdsupremacist/Graphaello
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/swift-objective-c-ios/client/graphql-ios.md b/src/code/language-support/swift-objective-c-ios/client/graphql-ios.md
index eae2fa2b4e..3423ff865f 100644
--- a/src/code/language-support/swift-objective-c-ios/client/graphql-ios.md
+++ b/src/code/language-support/swift-objective-c-ios/client/graphql-ios.md
@@ -2,4 +2,7 @@
name: GraphQL iOS
description: An Objective-C GraphQL client for iOS.
github: funcompany/graphql-ios
+tags:
+ - tools-and-libraries
+ - frontend
---
diff --git a/src/code/language-support/swift-objective-c-ios/client/swift-graphql.md b/src/code/language-support/swift-objective-c-ios/client/swift-graphql.md
index 9154277cf6..76bee36579 100644
--- a/src/code/language-support/swift-objective-c-ios/client/swift-graphql.md
+++ b/src/code/language-support/swift-objective-c-ios/client/swift-graphql.md
@@ -2,6 +2,9 @@
name: SwiftGraphQL
description: A GraphQL client that lets you forget about GraphQL.
github: maticzav/swift-graphql
+tags:
+ - tools-and-libraries
+ - frontend
---
SwiftGraphQL is a Swift code generator and a lightweight GraphQL client. It lets you create queries using Swift, and guarantees that every query you create is valid.
diff --git a/src/code/language-support/swift-objective-c-ios/server/graphiti.md b/src/code/language-support/swift-objective-c-ios/server/graphiti.md
index 870bf9c189..7a9f72ba25 100644
--- a/src/code/language-support/swift-objective-c-ios/server/graphiti.md
+++ b/src/code/language-support/swift-objective-c-ios/server/graphiti.md
@@ -2,4 +2,7 @@
name: Graphiti
description: Swift library for building GraphQL schemas/types fast, safely and easily.
github: GraphQLSwift/Graphiti
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/language-support/swift-objective-c-ios/server/graphzahl.md b/src/code/language-support/swift-objective-c-ios/server/graphzahl.md
index 98b2078d72..7429006ba2 100644
--- a/src/code/language-support/swift-objective-c-ios/server/graphzahl.md
+++ b/src/code/language-support/swift-objective-c-ios/server/graphzahl.md
@@ -2,4 +2,7 @@
name: GraphZahl
description: Swift library for writing Declarative, Type-Safe GraphQL APIs with Zero Boilerplate.
github: nerdsupremacist/GraphZahl
+tags:
+ - tools-and-libraries
+ - backend
---
diff --git a/src/code/services/altair.md b/src/code/services/altair.md
index ff359cc4c4..c152182b52 100644
--- a/src/code/services/altair.md
+++ b/src/code/services/altair.md
@@ -3,4 +3,7 @@ name: Altair
description: An alternative to Postman that supports editing GraphQL queries directly and autoload your GraphQL schema.
url: https://altair.sirmuel.design/
github: altair-graphql/altair
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/apideck.md b/src/code/services/apideck.md
index 034483f787..1d2294f3bf 100644
--- a/src/code/services/apideck.md
+++ b/src/code/services/apideck.md
@@ -2,4 +2,6 @@
name: Apideck
description: A GraphQL API to query and mutate data across APIs like Salesforce, HubSpot, Microsoft Dynamics, Pipedrive, and many more.
url: https://www.apideck.com/products/graphql/
+tags:
+ - tools-and-libraries
---
diff --git a/src/code/services/apisix.md b/src/code/services/apisix.md
index 4f8fc4ecdd..42dfd09797 100644
--- a/src/code/services/apisix.md
+++ b/src/code/services/apisix.md
@@ -3,4 +3,8 @@ name: Apache APISIX
description: Apache APISIX is a dynamic, real-time, high-performance API gateway providing rich traffic management features such as load balancing, dynamic upstream, canary release, observability, etc. As a cloud-native API gateway, Apache APISIX already can support GraphQL syntax at the beginning of its design. Efficiently matching GraphQL statements carried in requests can filter out abnormal traffic to further ensure security. For more information, please visit [How to Use GraphQL with API Gateway Apache APISIX](https://apisix.apache.org/blog/2022/03/02/apisix-integration-graphql-plugin/)
url: https://apisix.apache.org/
github: apache/apisix
+tags:
+ - tools-and-libraries
+ - tools
+ - monitoring
---
diff --git a/src/code/services/apollo-studio.md b/src/code/services/apollo-studio.md
index 5807a1f694..6314516fc3 100644
--- a/src/code/services/apollo-studio.md
+++ b/src/code/services/apollo-studio.md
@@ -3,4 +3,8 @@ name: Apollo Studio
description: A cloud service that helps you build, validate, monitor and secure your organizations data graph.
url: https://www.apollographql.com/docs/studio/
github: apollographql/apollo-studio-community
+tags:
+ - tools-and-libraries
+ - tools
+ - monitoring
---
diff --git a/src/code/services/aws-appsync.md b/src/code/services/aws-appsync.md
index c489d392a9..2d78b98937 100644
--- a/src/code/services/aws-appsync.md
+++ b/src/code/services/aws-appsync.md
@@ -2,4 +2,9 @@
name: AWS AppSync
description: Fully managed GraphQL service with realtime subscriptions, offline programming & synchronization, and enterprise security features as well as fine grained authorization controls.
url: https://aws.amazon.com/appsync/
+tags:
+ - tools-and-libraries
+ - tools
+ - security
+ - ai
---
diff --git a/src/code/services/back4app.md b/src/code/services/back4app.md
index da93824784..017aa8afd2 100644
--- a/src/code/services/back4app.md
+++ b/src/code/services/back4app.md
@@ -2,4 +2,6 @@
name: Back4App
description: Fully managed GraphQL backend based on open source Parse Platform. Store and query relational data, run cloud functions and more over GraphQL API. Free to get started.
url: https://www.back4app.com/docs/parse-graphql/graphql-getting-started
+tags:
+ - tools-and-libraries
---
diff --git a/src/code/services/bananacakepop.md b/src/code/services/bananacakepop.md
index 4efdc494fe..5208981c80 100644
--- a/src/code/services/bananacakepop.md
+++ b/src/code/services/bananacakepop.md
@@ -3,4 +3,7 @@ name: Banana Cake Pop
description: A feature-rich GraphQL IDE by [ChilliCream](https://chillicream.com) that let's you explore, manage, and test your GraphQL APIs. Check it out [here](https://bananacakepop.com).
url: https://bananacakepop.com
github: ChilliCream/hotchocolate
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/dgraph.md b/src/code/services/dgraph.md
index 3db97cd6be..5b86138c4c 100644
--- a/src/code/services/dgraph.md
+++ b/src/code/services/dgraph.md
@@ -3,6 +3,9 @@ name: Dgraph
description: Dgraph is a native GraphQL database with a graph backend. This means Dgraph is not an interface on top of an existing database like Postgres but is actually designed from the ground-up for GraphQL. It is optimized for speed and performance, depending on multiple computer science breakthroughs to get the best result. Dgraph Cloud is a fully managed GraphQL backend service that lets you iterate faster, without worrying about your infrastructure.
url: https://dgraph.io/graphql
github: dgraph-io/dgraph
+tags:
+ - tools-and-libraries
+ - tools
---
Install Steps if running locally on linux not on Dgraph Cloud:
diff --git a/src/code/services/elide.md b/src/code/services/elide.md
index 1dcb448fb3..4b0b2b2c13 100644
--- a/src/code/services/elide.md
+++ b/src/code/services/elide.md
@@ -3,4 +3,7 @@ name: Elide
description: A Java library that can expose a JPA annotated data model as a GraphQL service over any relational database.
url: https://elide.io
github: yahoo/elide
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/escape.md b/src/code/services/escape.md
index e9bf0b6f50..b8d722443d 100644
--- a/src/code/services/escape.md
+++ b/src/code/services/escape.md
@@ -2,4 +2,7 @@
name: Escape – GraphQL Security
description: Live GraphQL Security & Compliance. Ensure your GraphQL endpoints are production-ready. During development. Without needed configuration. Supports every language and framework. Free to get started.
url: https://escape.tech/
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/faunadb.md b/src/code/services/faunadb.md
index f966250dd3..7d25265d6d 100644
--- a/src/code/services/faunadb.md
+++ b/src/code/services/faunadb.md
@@ -2,4 +2,7 @@
name: FaunaDB
description: Create an instant GraphQL backend by importing a gql schema. The database will create relations and indexes for you, so you'll be ready to query in seconds, without writing any database code. Serverless pricing, free to get started.
url: https://docs.fauna.com/fauna/current/graphql
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/flotiq.md b/src/code/services/flotiq.md
index 5bfaf0a024..0a3238e1fb 100644
--- a/src/code/services/flotiq.md
+++ b/src/code/services/flotiq.md
@@ -2,4 +2,7 @@
name: Flotiq
description: Headless CMS that pairs a modern content editing experience with robust content personalisation and scheduling capabilities. It delivers your content through a blazing-fast, API-first delivery using GraphQL and REST endpoints.
url: https://flotiq.com
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/grafbase.md b/src/code/services/grafbase.md
index 2444f91ad7..1a35098acb 100644
--- a/src/code/services/grafbase.md
+++ b/src/code/services/grafbase.md
@@ -2,4 +2,7 @@
name: Grafbase
description: Grafbase provides secure self-hosted deployment options for GraphQL Federation, unmatched query speed, advanced governance, and unified data access for reliable, enterprise-grade API management. Learn more about scaling GraphQL Federation with [Grafbase](https://grafbase.com).
url: https://grafbase.com
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/graphapi.md b/src/code/services/graphapi.md
index eb469660f0..fa6791987f 100644
--- a/src/code/services/graphapi.md
+++ b/src/code/services/graphapi.md
@@ -3,4 +3,7 @@ name: graphapi®
description: graphapi® is a secure low-code GraphQL-as-a-service platform. Based on the input data model, it auto-generates the GraphQL schema, all resolvers, and the database stack. Additionally, it provides a user interface allowing teams to manage their data. For more information, go to https://graphapi.com.
url: https://graphapi.com/docs
github: graphapi-io/resources
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/graphql.security.md b/src/code/services/graphql.security.md
index 9f745d97ad..d8941e94b1 100644
--- a/src/code/services/graphql.security.md
+++ b/src/code/services/graphql.security.md
@@ -2,4 +2,7 @@
name: GraphQL.Security
description: Fast and free security scan to run a dozen of tests on a GraphQL endpoint. No login is required.
url: https://graphql.security/
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/hasura.md b/src/code/services/hasura.md
index 56e9fd0d91..8ffef04c57 100644
--- a/src/code/services/hasura.md
+++ b/src/code/services/hasura.md
@@ -3,4 +3,7 @@ name: Hasura
description: Hasura connects to your databases & microservices and instantly gives you a production-ready GraphQL API.
url: https://hasura.io
github: hasura/graphql-engine
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/hive.md b/src/code/services/hive.md
index 1841523ddb..29bd3df450 100644
--- a/src/code/services/hive.md
+++ b/src/code/services/hive.md
@@ -3,4 +3,8 @@ name: Hive
description: Hive is a fully open-source schema registry, analytics and gateway for GraphQL federation and other GraphQL APIs.
url: https://the-guild.dev/graphql/hive
github: graphql-hive/platform
+tags:
+ - tools-and-libraries
+ - tools
+ - monitoring
---
diff --git a/src/code/services/hygraph.md b/src/code/services/hygraph.md
index 09c79e592d..390d9b20ae 100644
--- a/src/code/services/hygraph.md
+++ b/src/code/services/hygraph.md
@@ -2,4 +2,7 @@
name: Hygraph
description: Hygraph is the federated content platform that allows true composability of your stack. Integrate all your services with a unique content federation approach and distribute content from anywhere - to anywhere using a single, powerful GraphQL API.
url: https://hygraph.com/
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/insomnia.md b/src/code/services/insomnia.md
index e0456997df..fef3206a47 100644
--- a/src/code/services/insomnia.md
+++ b/src/code/services/insomnia.md
@@ -3,4 +3,7 @@ name: Insomnia
description: Insomnia is an open-source, cross-platform API Client for GraphQL, REST, and gRPC. Insomnia combines an easy-to-use interface with advanced functionality like authentication helpers, code generation, and environment variables.
url: https://docs.insomnia.rest/insomnia/graphql-queries
github: Kong/insomnia
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/lexascms.md b/src/code/services/lexascms.md
index 401ac753e8..0d27b10033 100644
--- a/src/code/services/lexascms.md
+++ b/src/code/services/lexascms.md
@@ -2,4 +2,7 @@
name: LexasCMS
description: A headless CMS (Content Management System) that combines powerful content personalisation and scheduling capabilities with a modern content editing experience and a blazing fast GraphQL/REST content delivery API.
url: https://www.lexascms.com
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/moesif-api-analytics.md b/src/code/services/moesif-api-analytics.md
index 267efe4a0d..835c8589f9 100644
--- a/src/code/services/moesif-api-analytics.md
+++ b/src/code/services/moesif-api-analytics.md
@@ -2,4 +2,8 @@
name: Moesif API Analytics
description: A GraphQL analaytics and monitoring Service to find functional and performance issues.
url: https://www.moesif.com/features/graphql-analytics
+tags:
+ - tools-and-libraries
+ - tools
+ - monitoring
---
diff --git a/src/code/services/postman.md b/src/code/services/postman.md
index acd8f09b6c..cab9c33627 100644
--- a/src/code/services/postman.md
+++ b/src/code/services/postman.md
@@ -3,4 +3,7 @@ name: Postman
description: A robust multi-protocol API client with features like API scripting, automation, collaborative workspaces, and comprehensive support for testing and developing GraphQL APIs.
url: https://www.postman.com/product/graphql-client/
github: postmanlabs/postman-app-support
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/stepzen.md b/src/code/services/stepzen.md
index c5eebe3de1..2d0eca3d50 100644
--- a/src/code/services/stepzen.md
+++ b/src/code/services/stepzen.md
@@ -3,4 +3,7 @@ name: StepZen
description: Create a serverless GraphQL API based on your data sources (REST & Databases), Third-Party APIs, or any combination. Instead of writing a GraphQL server yourself, you can define everything declaratively by writing GraphQL schemas. For more information, go to https://www.stepzen.com/.
url: https://stepzen.com/docs/
github: stepzen-dev/examples
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/tyk.md b/src/code/services/tyk.md
index a00e8e23a0..750bab2035 100644
--- a/src/code/services/tyk.md
+++ b/src/code/services/tyk.md
@@ -3,4 +3,7 @@ name: Tyk
description: Tyk is a lightweight Open Source API Management Gateway that has built a Full API Life-Cycle Management around GraphQL with its own GraphQL engine that is written in Golang. Tyk supports schema stitching of multiple GraphQL and/or REST APIs through [Universal Data Graph (UDG)](https://tyk.io/docs/universal-data-graph/) as well as [GraphQL Federation](https://tyk.io/docs/getting-started/key-concepts/graphql-federation/) and [GraphQL Subscription](https://tyk.io/docs/getting-started/key-concepts/graphql-subscriptions/).
url: https://tyk.io/
github: TykTechnologies/tyk
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/typetta.md b/src/code/services/typetta.md
index 1458357009..24329c8e65 100644
--- a/src/code/services/typetta.md
+++ b/src/code/services/typetta.md
@@ -4,4 +4,7 @@ description: Typetta is an open-source ORM written in TypeScript that aims to al
url: https://twinlogix.github.io/typetta/
github: twinlogix/typetta
npm: "@twinlogix/typetta"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/services/webiny.md b/src/code/services/webiny.md
index f665b145d2..3c15936a04 100644
--- a/src/code/services/webiny.md
+++ b/src/code/services/webiny.md
@@ -3,4 +3,7 @@ name: Webiny
description: Webiny allows you to quickly build GraphQL APIs on top of AWS Lambda and DynamoDB with built-in scaffolds. Webiny also includes a ready-made headless GraphQL CMS for a no-code experience.
url: https://www.webiny.com
github: webiny/webiny-js
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/tools/apollo/gateways-supergraphs/apollo-router.md b/src/code/tools/apollo/gateways-supergraphs/apollo-router.md
index 673799714a..7a9ba9c480 100644
--- a/src/code/tools/apollo/gateways-supergraphs/apollo-router.md
+++ b/src/code/tools/apollo/gateways-supergraphs/apollo-router.md
@@ -3,6 +3,10 @@ name: Apollo Router
description: A configurable, high-performance routing runtime for Apollo Federation
url: https://www.apollographql.com/
github: apollographql/router
+tags:
+ - tools-and-libraries
+ - tools
+ - federation
---
# Apollo Router Core
diff --git a/src/code/tools/gqt/general/gqt.md b/src/code/tools/gqt/general/gqt.md
index b5f9872827..d3e5a32bbd 100644
--- a/src/code/tools/gqt/general/gqt.md
+++ b/src/code/tools/gqt/general/gqt.md
@@ -2,6 +2,9 @@
name: gqt
description: Build and execute GraphQL queries in the terminal.
github: eerimoq/gqt
+tags:
+ - tools-and-libraries
+ - tools
---
Run `gqt` against your GraphQL endpoint. Build your query in an
diff --git a/src/code/tools/graphql-armor/general/graphql-armor.md b/src/code/tools/graphql-armor/general/graphql-armor.md
index 2075a67136..68ef9956ff 100644
--- a/src/code/tools/graphql-armor/general/graphql-armor.md
+++ b/src/code/tools/graphql-armor/general/graphql-armor.md
@@ -3,4 +3,7 @@ name: GraphQL Armor
description: The missing GraphQL security layer for Apollo GraphQL and Yoga / Envelop servers.
github: Escape-Technologies/graphql-armor
npm: "@Escape-Technologies/graphql-armor"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/tools/graphql-code-generator/general/graphql-code-generator.md b/src/code/tools/graphql-code-generator/general/graphql-code-generator.md
index 1ba0a96afb..2c415bbad4 100644
--- a/src/code/tools/graphql-code-generator/general/graphql-code-generator.md
+++ b/src/code/tools/graphql-code-generator/general/graphql-code-generator.md
@@ -4,4 +4,7 @@ description: GraphQL code generator with flexible support for custom plugins and
url: https://graphql-code-generator.com
github: dotansimha/graphql-code-generator
npm: "@graphql-codegen/cli"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/tools/graphql-protect/general/graphql-protect.md b/src/code/tools/graphql-protect/general/graphql-protect.md
index d31f77e2db..e4f32b029c 100644
--- a/src/code/tools/graphql-protect/general/graphql-protect.md
+++ b/src/code/tools/graphql-protect/general/graphql-protect.md
@@ -1,8 +1,10 @@
---
name: GraphQL Protect
description: GraphQL Protect is a GraphQL Protect is dead-simple yet highly customizable security proxy compatible with any HTTP GraphQL Server or Gateway.
-#url: https://github.com/ldebruijn/graphql-protect/
github: ldebruijn/graphql-protect
+tags:
+ - tools-and-libraries
+ - tools
---
[GraphQL Protect](https://github.com/ldebruijn/graphql-protect) helps you protect your GraphQL API against abuse by providing a large number of plug-and-play protection mechanism with sane defaults, while still allowing you complete customizability.
diff --git a/src/code/tools/hive/gateways-supergraphs/hive.md b/src/code/tools/hive/gateways-supergraphs/hive.md
index af42b94f1e..dc11cba76a 100644
--- a/src/code/tools/hive/gateways-supergraphs/hive.md
+++ b/src/code/tools/hive/gateways-supergraphs/hive.md
@@ -3,6 +3,9 @@ name: Hive Gateway
description: Hive Gateway can act as a GraphQL federation gateway or a proxy for any GraphQL service.
url: https://the-guild.dev/graphql/hive
github: graphql-hive/gateway
+tags:
+ - tools-and-libraries
+ - tools
---
[Hive Gateway](https://the-guild.dev/graphql/hive/docs/gateway) is a fully open-source, MIT-licensed GraphQL router that can act as a [GraphQL Federation](https://the-guild.dev/graphql/hive/federation) gateway, a subgraph or a proxy gateway for any GraphQL API service.
diff --git a/src/code/tools/microcks/general/microcks.md b/src/code/tools/microcks/general/microcks.md
index 20a3e02907..9ad15fa3fd 100644
--- a/src/code/tools/microcks/general/microcks.md
+++ b/src/code/tools/microcks/general/microcks.md
@@ -3,6 +3,9 @@ name: Microcks
description: Open source Kubernetes-native tool for API Mocking and Testing
url: https://microcks.io
github: microcks/microcks
+tags:
+ - tools-and-libraries
+ - tools
---
Microcks is a platform for turning your API and microservices assets - _GraphQL schemas_, _OpenAPI specs_, _AsyncAPI specs_, _gRPC protobuf_, _Postman collections_, _SoapUI projects_\_ - into live simulations in seconds.
diff --git a/src/code/tools/quicktype/general/quicktype.md b/src/code/tools/quicktype/general/quicktype.md
index 14314b3cae..06afabb73a 100644
--- a/src/code/tools/quicktype/general/quicktype.md
+++ b/src/code/tools/quicktype/general/quicktype.md
@@ -4,4 +4,7 @@ description: Generate types for GraphQL queries in TypeScript, Swift, golang, C#
url: https://quicktype.io/
github: glideapps/quicktype
npm: "quicktype"
+tags:
+ - tools-and-libraries
+ - tools
---
diff --git a/src/code/tools/schemathesis/general/schemathesis.md b/src/code/tools/schemathesis/general/schemathesis.md
index da8096309c..8e9015381b 100644
--- a/src/code/tools/schemathesis/general/schemathesis.md
+++ b/src/code/tools/schemathesis/general/schemathesis.md
@@ -2,6 +2,9 @@
name: Schemathesis
description: A modern API testing tool for web applications built with Open API and GraphQL specifications.
github: schemathesis/schemathesis
+tags:
+ - tools-and-libraries
+ - tools
---
Run Schemathesis via Docker against your GraphQL endpoint:
diff --git a/src/code/tools/wundergraph/gateways-supergraphs/wundergraph.md b/src/code/tools/wundergraph/gateways-supergraphs/wundergraph.md
index a06fe9a0ab..09422caa04 100644
--- a/src/code/tools/wundergraph/gateways-supergraphs/wundergraph.md
+++ b/src/code/tools/wundergraph/gateways-supergraphs/wundergraph.md
@@ -3,6 +3,9 @@ name: Wundergraph Cosmo
description: The open-source solution to building, maintaining, and collaborating on GraphQL Federation at Scale. The alternative to Apollo Studio and GraphOS.
url: https://wundergraph.com/
github: wundergraph/cosmo
+tags:
+ - tools-and-libraries
+ - tools
---
[WunderGraph](https://wundergraph.com) composes all your APIs into a single unified GraphQL API and
diff --git a/src/components/blog-page/blog-card-picture.tsx b/src/components/blog-page/blog-card-picture.tsx
index 0bb4f386c8..bbc10b6bbf 100644
--- a/src/components/blog-page/blog-card-picture.tsx
+++ b/src/components/blog-page/blog-card-picture.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { clsx } from "clsx"
import { type ReactNode, useEffect, useRef } from "react"
diff --git a/src/components/blog-page/blog-card.tsx b/src/components/blog-page/blog-card.tsx
index 349f5b4454..00c56e87b1 100644
--- a/src/components/blog-page/blog-card.tsx
+++ b/src/components/blog-page/blog-card.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { clsx } from "clsx"
import NextLink from "next/link"
diff --git a/src/components/blog-page/blog-categories.tsx b/src/components/blog-page/blog-categories.tsx
new file mode 100644
index 0000000000..2b7a70367a
--- /dev/null
+++ b/src/components/blog-page/blog-categories.tsx
@@ -0,0 +1,10 @@
+export const blogCategories = [
+ "newsletter",
+ "announcements",
+ "blog",
+ "foundation",
+ "spec",
+ "grants",
+ "in-the-news",
+ "developer-experience",
+] as const
diff --git a/src/components/blog-page/blog-tag-colors.tsx b/src/components/blog-page/blog-tag-colors.tsx
deleted file mode 100644
index 0a69f779d6..0000000000
--- a/src/components/blog-page/blog-tag-colors.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-export const blogTagColors: Record = {
- newsletter: "#FFCCEF",
- announcements: "#F80",
- blog: "#012FFF",
- foundation: "#5800FF",
- spec: "#00C6AC",
- grants: "#84BD01",
- "in-the-news": "#3F3A3D",
-}
diff --git a/src/components/blog-page/blog-tags.tsx b/src/components/blog-page/blog-tags.tsx
index 6c1a509535..4756568d5e 100644
--- a/src/components/blog-page/blog-tags.tsx
+++ b/src/components/blog-page/blog-tags.tsx
@@ -2,7 +2,7 @@ import NextLink from "next/link"
import { Tag } from "@/app/conf/_design-system/tag"
-import { blogTagColors } from "./blog-tag-colors"
+import { tagColors } from "@/app/conf/_design-system/tag-colors"
import clsx from "clsx"
export function BlogTags({
@@ -11,7 +11,7 @@ export function BlogTags({
className,
links,
}: {
- tags: string[]
+ tags: readonly string[]
opaque?: boolean
className?: string
links?: boolean
@@ -19,7 +19,7 @@ export function BlogTags({
return (
{tags.map(tag => {
- const color = blogTagColors[tag]
+ const color = tagColors[tag as keyof typeof tagColors]
if (!color && process.env.NODE_ENV !== "production") {
throw new Error(`No color found for tag: ${tag}`)
}
@@ -35,7 +35,7 @@ export function BlogTags({
key={tag}
// yes, the page lives under /tags, not /blog/tags
href={`/tags/${tag}`}
- className="-m-1 flex p-1 ring-inset ring-neu-400 transition-opacity duration-75 hover:ring focus:!outline-offset-0 dark:ring-neu-50 [:has(>:hover)>&:not(:hover)]:opacity-70"
+ className="gql-focus-visible -m-1 flex p-1 ring-inset ring-neu-400 transition-opacity duration-75 hover:ring focus:!outline-offset-0 dark:ring-neu-50 [:has(>:hover)>&:not(:hover)]:opacity-70"
>
{tagElement}
diff --git a/src/components/blog-page/featured-blog-posts.tsx b/src/components/blog-page/featured-blog-posts.tsx
index fc6c7f08cc..d017dfd39b 100644
--- a/src/components/blog-page/featured-blog-posts.tsx
+++ b/src/components/blog-page/featured-blog-posts.tsx
@@ -47,7 +47,7 @@ export function FeaturedBlogPosts({
byline={firstFeatured.frontMatter.byline}
date={firstFeatured.frontMatter.date}
/>
-
+
diff --git a/src/components/blog-page/index.tsx b/src/components/blog-page/index.tsx
index 0d597d3b7e..57241ff40b 100644
--- a/src/components/blog-page/index.tsx
+++ b/src/components/blog-page/index.tsx
@@ -5,11 +5,12 @@ import { Tag } from "@/app/conf/_design-system/tag"
import { arrowsMoveSideways } from "@/app/conf/_design-system/utils/arrows-move-sideways"
import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
-import { blogTagColors } from "./blog-tag-colors"
+import { LookingForMore } from "@/components/looking-for-more"
+
import { BlogCard } from "./blog-card"
-import { LookingForMore } from "./looking-for-more"
import { BlogMdxContent } from "./mdx-types"
import { FeaturedBlogPosts } from "./featured-blog-posts"
+import { tagColors } from "@/app/conf/_design-system/tag-colors"
const mask = `url(${new URL("./blur-bean.webp", import.meta.url).href})`
@@ -51,14 +52,14 @@ export function BlogPage({
-
+
{currentTag || "All Posts"}
Categories
-
+
{Object.entries(tags)
.sort((a, b) => b[1] - a[1])
.map(([tag, count], i) => (
@@ -70,7 +71,7 @@ export function BlogPage({
className="-m-1 flex p-1 ring-inset ring-neu-400 transition-opacity duration-75 hover:ring focus:!outline-offset-0 dark:ring-neu-50 [:has(>:hover)>&:not(:hover)]:opacity-70"
onKeyDown={arrowsMoveSideways}
>
-
+
{tag.replaceAll("-", " ")} ({count})
@@ -78,7 +79,7 @@ export function BlogPage({
-
+
{blogs.map(
page =>
(!currentTag || page.frontMatter.tags.includes(currentTag)) && (
@@ -87,7 +88,13 @@ export function BlogPage({
)}
-
+
)
diff --git a/src/components/blog-page/looking-for-more.tsx b/src/components/blog-page/looking-for-more.tsx
deleted file mode 100644
index 2441ade4e7..0000000000
--- a/src/components/blog-page/looking-for-more.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Anchor } from "@/app/conf/_design-system/anchor"
-
-import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
-
-export function LookingForMore() {
- return (
-
-
-
-
Looking for more?
-
- Explore learning guides and best practices — or browse for tools,
- libraries and other resources.
-
-
-
-
- Learn
-
-
-
- Resources
-
-
-
-
-
- )
-}
diff --git a/src/components/learn-aggregator/learn-hero-stripes.tsx b/src/components/learn-aggregator/learn-hero-stripes.tsx
index 29d2a4e37f..b7692117a3 100644
--- a/src/components/learn-aggregator/learn-hero-stripes.tsx
+++ b/src/components/learn-aggregator/learn-hero-stripes.tsx
@@ -1,13 +1,24 @@
+import { clsx } from "clsx"
import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
import blurBean from "./learn-blur-bean.webp"
-export function LearnHeroStripes() {
+export function LearnHeroStripes({
+ className,
+ style,
+ ...rest
+}: {
+ className?: string
+ style?: React.CSSProperties
+}) {
return (
+export type LearnPagePath = Exclude
-interface LearnPageItem {
+export interface LearnPageItem {
title: string
description: string
icon: string
diff --git a/src/components/learn-aggregator/looking-for-more.tsx b/src/components/learn-aggregator/looking-for-more.tsx
deleted file mode 100644
index 95c719ad66..0000000000
--- a/src/components/learn-aggregator/looking-for-more.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-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/components/learn-aggregator/teaser-section-list-item.tsx b/src/components/learn-aggregator/teaser-section-list-item.tsx
new file mode 100644
index 0000000000..0429807118
--- /dev/null
+++ b/src/components/learn-aggregator/teaser-section-list-item.tsx
@@ -0,0 +1,69 @@
+import { clsx } from "clsx"
+
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+
+export interface TeaserSectionListItemProps
+ extends React.HTMLAttributes {
+ number?: number
+ title: string
+ description: string
+ icon: React.ReactNode
+ section: "getting-started" | "best-practices"
+ href: string
+}
+export function TeaserSectionListItem({
+ number,
+ title,
+ description,
+ icon,
+ section,
+ href,
+ className,
+ ...rest
+}: TeaserSectionListItemProps) {
+ return (
+
+
+
+ {icon}
+
+
+
+ {number !== undefined && (
+
+ {/* TODO: Are we really sure these are Lessons? */}
+ Lesson {number}
+
+ )}
+
+ {title}
+
+
+
+
+ {description}
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/learn-aggregator/teaser-section.tsx b/src/components/learn-aggregator/teaser-section.tsx
index d29c6fc87a..3f5c213f7f 100644
--- a/src/components/learn-aggregator/teaser-section.tsx
+++ b/src/components/learn-aggregator/teaser-section.tsx
@@ -1,12 +1,11 @@
import { ReactNode, useState } from "react"
import { clsx } from "clsx"
-import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
-
import { Eyebrow } from "@/_design-system/eyebrow"
-
import { Button } from "@/app/conf/_design-system/button"
+import { TeaserSectionListItem } from "./teaser-section-list-item"
+
export interface TeaserSectionProps
extends React.HTMLAttributes {
eyebrow: string
@@ -95,62 +94,3 @@ export function TeaserSection({
)
}
-
-interface TeaserSectionListItemProps
- extends React.HTMLAttributes {
- number: number
- title: string
- description: string
- icon: ReactNode
- section: "getting-started" | "best-practices"
- href: string
-}
-function TeaserSectionListItem({
- number,
- title,
- description,
- icon,
- section,
- href,
- className,
- ...rest
-}: TeaserSectionListItemProps) {
- return (
-
-
-
- {icon}
-
-
-
-
- {/* TODO: Are we really sure these are Lessons? */}
- Lesson {number}
-
-
- {title}
-
-
-
-
- {description}
-
-
-
-
-
-
-
- )
-}
diff --git a/src/components/looking-for-more.tsx b/src/components/looking-for-more.tsx
new file mode 100644
index 0000000000..db174b300d
--- /dev/null
+++ b/src/components/looking-for-more.tsx
@@ -0,0 +1,46 @@
+import { clsx } from "clsx"
+import { Anchor } from "@/app/conf/_design-system/anchor"
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+
+type LinkItem = { href: string; label: string }
+
+interface LookingForMoreProps extends React.HTMLAttributes {
+ description: string
+ links: [LinkItem, LinkItem]
+}
+
+export function LookingForMore({
+ description,
+ links,
+ ...props
+}: LookingForMoreProps) {
+ return (
+
+
+
+
Looking for more?
+
{description}
+
+
+
+ {links[0].label}
+
+
+
+ {links[1].label}
+
+
+
+
+
+ )
+}
diff --git a/src/components/nav-links/arrow-nav-links.tsx b/src/components/nav-links/arrow-nav-links.tsx
index 9e70684c1f..6563ad511b 100644
--- a/src/components/nav-links/arrow-nav-links.tsx
+++ b/src/components/nav-links/arrow-nav-links.tsx
@@ -36,7 +36,7 @@ export function ArrowNavLinks({
title={prev.title}
className="gql-focus-visible typography-link flex max-w-[50%] items-center gap-2 border border-neu-200 pr-2 text-left text-base no-underline hover:bg-neu-50 hover:ring hover:ring-neu-100 dark:border-neu-100 dark:hover:bg-neu-50/50 dark:hover:ring-neu-50"
>
-
+
{prev.title}
@@ -49,7 +49,7 @@ export function ArrowNavLinks({
className="gql-focus-visible typography-link ml-auto flex max-w-[50%] items-center gap-2 border border-neu-200 pl-2 text-left text-base no-underline hover:bg-neu-50 hover:ring hover:ring-neu-100 dark:border-neu-100 dark:hover:bg-neu-50/50 dark:hover:ring-neu-50"
>
{next.title}
-
+
diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx
index d0e9d8fcbd..64b826850e 100644
--- a/src/components/navbar/navbar.tsx
+++ b/src/components/navbar/navbar.tsx
@@ -18,6 +18,8 @@ import { Flexsearch } from "../flexsearch"
import { NavLink, navLinkClasses } from "./nav-link"
import { useMenu } from "../use-menu"
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+
type Item = normalizePages.PageItem | normalizePages.MenuItem
export interface NavBarProps {
items: Item[]
@@ -33,6 +35,7 @@ function NavbarMenu({
const routes = Object.fromEntries(
(menu.children || []).map(route => [route.name, route]),
)
+
return (
- {Object.entries(menu.items || {}).map(([key, item]) => (
- ,
- state: NavigationMenu.Link.State,
- ) => (
-
-
- {item.title}
-
-
- )}
- />
- ))}
+ {Object.entries(menu.items || {}).map(([key, item]) => {
+ if (typeof item === "string") item = { title: item }
+ if (!item.title) item.title = key
+ const href =
+ item.href ||
+ routes[key]?.route ||
+ (key === "index" ? menu.route : `${menu.route}/${key}`)
+
+ if (key === "index") {
+ return (
+ ,
+ state: NavigationMenu.Link.State,
+ ) => (
+
+
+ Explore {menu.title}
+
+
+
+ )}
+ />
+ )
+ }
+
+ return (
+ ,
+ state: NavigationMenu.Link.State,
+ ) => (
+
+
+ {item.title}
+
+
+ )}
+ />
+ )
+ })}
)
diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx
index bd126b6d5e..e8d3969b5b 100644
--- a/src/components/sidebar/index.tsx
+++ b/src/components/sidebar/index.tsx
@@ -31,6 +31,8 @@ import {
import ArrowBarLeft from "@/app/conf/_design-system/pixelarticons/arrow-bar-left.svg?svgr"
import { Anchor } from "@/app/conf/_design-system/anchor"
+import ArrowDownIcon from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr"
+import CaretDownIcon from "@/app/conf/_design-system/pixelarticons/caret-down.svg?svgr"
import { renderComponent } from "../utils/render-component"
import { ThemeSwitch } from "../theme-switch"
@@ -57,7 +59,7 @@ const Folder = memo(function FolderInner(props: FolderProps) {
const classes = {
link: cn(
- "flex px-2 py-1.5 text-sm transition-colors [word-break:break-word]",
+ "flex px-2 capitalize py-1.5 text-sm transition-colors [word-break:break-word]",
"cursor-pointer contrast-more:border contrast-more:hover:underline gql-focus-visible focus-visible:outline-offset-1",
),
inactive: cn(
@@ -143,10 +145,16 @@ function FolderImpl({ item, anchors, onFocus }: FolderProps): ReactElement {
(menu.children || []).map(route => [route.name, route]),
)
item.children = Object.entries(menu.items || {}).map(([key, item]) => {
+ if (typeof item === "string") item = { title: item }
+ if (!item.title) item.title = key
+
const route = routes[key] || {
name: key,
route: menu.route + "/" + key,
}
+
+ if (key === "index") route.route = menu.route
+
return {
...route,
...item,
@@ -199,12 +207,11 @@ function FolderImpl({ item, anchors, onFocus }: FolderProps): ReactElement {
onFocus={onFocus}
>
{item.title}
-
@@ -273,13 +280,24 @@ function File({
{
setMenu(false)
}}
onFocus={onFocus}
>
- {item.title}
+ {item.name !== "index" ? (
+ item.title
+ ) : (
+ <>
+ Explore {item.title}
+
+ >
+ )}
{active && anchors.length > 0 && (
diff --git a/src/components/toc-hero/toc-hero-contents.tsx b/src/components/toc-hero/toc-hero-contents.tsx
index 84f060efb3..9cd53f95b6 100644
--- a/src/components/toc-hero/toc-hero-contents.tsx
+++ b/src/components/toc-hero/toc-hero-contents.tsx
@@ -1,6 +1,7 @@
import { clsx } from "clsx"
import { ChevronRight } from "@/app/conf/_design-system/pixelarticons/chevron-right"
+import { slugify } from "@/app/(main)/resources/[category]/categories-config"
export interface TocHeroContentsProps
extends React.HTMLAttributes {
@@ -34,7 +35,7 @@ export function TocHeroContents({
typeof section === "string"
? {
name: section,
- href: `#${section.toLowerCase().replace(/ /g, "-")}`,
+ href: `#${slugify(section)}`,
}
: section
diff --git a/src/env.d.ts b/src/env.d.ts
index a5309effaf..dced5d24c3 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -17,6 +17,11 @@ declare module "*?raw" {
export default content
}
+declare module "*.svg?resource" {
+ const url: string
+ export default url
+}
+
// We're importing a transitive dependency to avoid a bug.
declare module "next-themes" {
export function ThemeProvider(props: {
diff --git a/src/pages/_meta.tsx b/src/pages/_meta.tsx
index 115fb056f2..3d1d63776e 100644
--- a/src/pages/_meta.tsx
+++ b/src/pages/_meta.tsx
@@ -10,22 +10,48 @@ export default {
type: "page",
title: "Learn",
},
- community: {
+ resources: {
type: "menu",
- title: "Community",
+ title: "Resource Hub",
+ route: "/resources",
items: {
+ index: "Resource Hub",
+ frontend: "",
+ backend: "",
+ federation: "",
+ ai: "AI",
+ security: "",
+ monitoring: "",
"tools-and-libraries": {
- title: "Tools and Libraries",
+ type: "page",
+ title: "Tools & Libraries",
+ // for now, until we have bandwidth to migrate it to App Router
+ href: "/community/tools-and-libraries",
},
- resources: {
- title: "Resources",
- href: "/community/resources/official-channels",
+ spec: {
+ type: "page",
+ title: "Specification",
+ href: "https://spec.graphql.org",
+ newWindow: true,
},
+ video: "Video Resources Library",
+ reading: "Reading Resources Library",
+ },
+ },
+ community: {
+ type: "menu",
+ title: "Community",
+ items: {
events: {
title: "Events",
type: "page",
href: "/community/events",
},
+ "official-channels": { title: "Official Channels" },
+ "training-courses": { title: "Training Courses" },
+ "community-channels": { title: "Community Channels" },
+ "vendor-channels": { title: "Vendor Channels" },
+ "more-resources": { title: "Community Resources" },
ambassadors: { title: "Ambassador Program" },
contribute: {
title: "Contribute to GraphQL",
@@ -35,15 +61,9 @@ export default {
},
},
faq: {
- type: "page",
+ type: "hidden",
title: "FAQ",
},
- spec: {
- type: "page",
- title: "Spec",
- href: "https://spec.graphql.org",
- newWindow: true,
- },
blog: {
type: "page",
title: "Blog",
diff --git a/src/pages/blog/2015-09-14-graphql.mdx b/src/pages/blog/2015-09-14-graphql.mdx
index 97cd48527c..6a1c8eb613 100644
--- a/src/pages/blog/2015-09-14-graphql.mdx
+++ b/src/pages/blog/2015-09-14-graphql.mdx
@@ -1,6 +1,6 @@
---
title: "GraphQL: A data query language"
-tags: ["blog", "spec"]
+tags: ["blog", "spec", frontend, backend]
date: 2015-09-14
byline: "Lee Byron"
---
diff --git a/src/pages/blog/2015-10-16-subscriptions.mdx b/src/pages/blog/2015-10-16-subscriptions.mdx
index 5a0318ebd7..9c0d2d28a4 100644
--- a/src/pages/blog/2015-10-16-subscriptions.mdx
+++ b/src/pages/blog/2015-10-16-subscriptions.mdx
@@ -1,6 +1,6 @@
---
title: "Subscriptions in GraphQL and Relay"
-tags: ["blog", "spec"]
+tags: ["blog", "spec", "frontend"]
date: 2015-10-16
byline: Dan Schafer and Laney Kuenzel
---
diff --git a/src/pages/blog/2016-04-19-mocking.mdx b/src/pages/blog/2016-04-19-mocking.mdx
index f77a19880b..083751aff0 100644
--- a/src/pages/blog/2016-04-19-mocking.mdx
+++ b/src/pages/blog/2016-04-19-mocking.mdx
@@ -1,7 +1,7 @@
---
title: "Mocking your server is easy with GraphQL"
date: 2016-04-19
-tags: ["blog"]
+tags: ["blog", "frontend"]
byline: "Jonas Helfer"
guestBio: engineer at Meteor working on Apollo
---
diff --git a/src/pages/blog/2020-12-08-defer-stream.mdx b/src/pages/blog/2020-12-08-defer-stream.mdx
index 94c1967323..4fab4d08a6 100644
--- a/src/pages/blog/2020-12-08-defer-stream.mdx
+++ b/src/pages/blog/2020-12-08-defer-stream.mdx
@@ -1,6 +1,6 @@
---
title: Improving Latency with @defer and @stream Directives
-tags: [announcements]
+tags: [announcements, frontend]
date: 2020-12-08
byline: Rob Richard, Liliana Matos
---
diff --git a/src/pages/blog/_meta.tsx b/src/pages/blog/_meta.tsx
index 97b97c62d4..78ab36871a 100644
--- a/src/pages/blog/_meta.tsx
+++ b/src/pages/blog/_meta.tsx
@@ -1,8 +1,5 @@
import { useConfig } from "nextra-theme-docs"
-import NextLink from "next/link"
-import { Tag } from "../../app/conf/_design-system/tag"
-import { blogTagColors } from "../../components/blog-page/blog-tag-colors"
import { BlogCardPicture } from "../../components/blog-page/blog-card-picture"
import { BlogMdxContent } from "../../components/blog-page/mdx-types"
import { BlogTags } from "../../components/blog-page/blog-tags"
diff --git a/src/pages/community/_meta.ts b/src/pages/community/_meta.ts
index 1746267b98..7b7c55a15a 100644
--- a/src/pages/community/_meta.ts
+++ b/src/pages/community/_meta.ts
@@ -1,5 +1,9 @@
export default {
- resources: "Resources",
+ "official-channels": "",
+ "training-courses": "",
+ "community-channels": "",
+ "vendor-channels": "",
+ "more-resources": "Community Resources",
"tools-and-libraries": {
theme: {
layout: "raw",
diff --git a/src/pages/community/resources/community-channels.mdx b/src/pages/community/community-channels.mdx
similarity index 92%
rename from src/pages/community/resources/community-channels.mdx
rename to src/pages/community/community-channels.mdx
index 8af52f5deb..f0508c82b5 100644
--- a/src/pages/community/resources/community-channels.mdx
+++ b/src/pages/community/community-channels.mdx
@@ -3,8 +3,8 @@ import {
ReactifluxIcon,
FreenodeIcon,
StackOverflowIcon,
-} from "../../../icons"
-import { Cards } from "../../../components/cards"
+} from "../../icons"
+import { Cards } from "../../components/cards"
# Community Channels
diff --git a/src/pages/community/resources/more-resources.mdx b/src/pages/community/more-resources.mdx
similarity index 98%
rename from src/pages/community/resources/more-resources.mdx
rename to src/pages/community/more-resources.mdx
index a663ec1b1c..05b3c3021b 100644
--- a/src/pages/community/resources/more-resources.mdx
+++ b/src/pages/community/more-resources.mdx
@@ -1,4 +1,4 @@
-# More Resources
+# Community Resources
To explore other community-developed resources and content about GraphQL, take a look at these sites:
diff --git a/src/pages/community/resources/official-channels.mdx b/src/pages/community/official-channels.mdx
similarity index 96%
rename from src/pages/community/resources/official-channels.mdx
rename to src/pages/community/official-channels.mdx
index ff165c4be5..8b4d263aea 100644
--- a/src/pages/community/resources/official-channels.mdx
+++ b/src/pages/community/official-channels.mdx
@@ -10,8 +10,8 @@ import {
CodeIcon,
GraphQLLogo,
FoundationTalksChannel
-} from "../../../icons"
-import { Cards } from "../../../components/cards"
+} from "../../icons"
+import { Cards } from "../../components/cards"
# Official Channels
diff --git a/src/pages/community/resources/_meta.ts b/src/pages/community/resources/_meta.ts
deleted file mode 100644
index 01ea2b60eb..0000000000
--- a/src/pages/community/resources/_meta.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export default {
- "official-channels": "",
- "training-courses": "",
- "community-channels": "",
- "blogs-and-newsletters": "",
- videos: "",
- "vendor-channels": "",
- books: "",
- "more-resources": "",
-}
diff --git a/src/pages/community/resources/blogs-and-newsletters.mdx b/src/pages/community/resources/blogs-and-newsletters.mdx
deleted file mode 100644
index 46331f19e2..0000000000
--- a/src/pages/community/resources/blogs-and-newsletters.mdx
+++ /dev/null
@@ -1,44 +0,0 @@
-# Blogs and Newsletters
-
-Popular sources to learn and keep track of the GraphQL Ecosystem.
-
-- [Official GraphQL Blog](https://graphql.org/blog)
-- [Apollo's Blog](https://apollographql.com/blog)
-- [ChilliCream's Blog](https://chillicream.com/blog)
-- [DEV.to GraphQL tag](https://dev.to/t/graphql)
-- [Escape Security Blog](https://escape.tech/blog)
-- [GraphQL Editor Blog](https://blog.graphqleditor.com)
-- [GraphQL WTF Episodes Feed](https://graphql.wtf)
-- [GraphQL Weekly](https://graphqlweekly.com)
-- [Hasura's Blog](https://hasura.io/blog)
-- [Inigo's Security Blog](https://inigo.io/blog)
-- [StepZen's Blog](https://stepzen.com/blog)
-- [The Guild's Blog](https://the-guild.dev/blog)
-- [The Guild's Newsletter](https://getrevue.co/profile/TheGuild)
-- [WunderGraph's Blog](https://wundergraph.com/blog)
-
-## Individual Posts
-
-Here are a list of notable blog posts to help you better understand GraphQL:
-
-- [GraphQL: A data query language](/blog/graphql-a-query-language/) - Lee Byron
-- [Subscriptions in GraphQL and Relay](/blog/subscriptions-in-graphql-and-relay/) - Dan Schafer and Laney Kuenzel
-- [Mocking your server is easy with GraphQL](/blog/mocking-with-graphql/) - Jonas Helfer
-- [Wrapping a REST API in GraphQL](/blog/rest-api-graphql-wrapper/) - Steven Luscher
-- [Leaving technical preview](/blog/production-ready/) - Lee Byron
-- [Relicensing the GraphQL specification](https://medium.com/@leeb/relicensing-the-graphql-specification-e7d07a52301b) - Lee Byron
-- [GraphQL Introduction](https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html) - Nick Schrock
-- [From REST to GraphQL](https://0x2a.sh/from-rest-to-graphql-b4e95e94c26b#.tag7nzkrb) - Jacob Gillespie
-- [GraphQL Explained](https://medium.com/apollo-stack/graphql-explained-5844742f195e#.zdykxos6i) - Jonas Helfer
-- [GraphQL Concepts Visualized](https://medium.com/apollo-stack/the-concepts-of-graphql-bc68bd819be3#.hfczgtdsj) - Dhaivat Pandya
-- [Building the f8 App: Using GraphQL & Relay](http://makeitopen.com/docs/en/1-A2-relay.html)
-- [Your First GraphQL Server](https://medium.com/the-graphqlhub/your-first-graphql-server-3c766ab4f0a2#.ovn0y19k4) - Clay Allsopp
-- [Tutorial: Kick start a JS API with Apollo-server, Dataloader and Knex](https://bamtech.gitbook.io/dev-standards/backend/graphql-js/getting-started-with-apollo-server-dataloader-knex.mo) - Thomas Pucci
-- [Tutorial: How to Build a GraphQL Server](https://medium.com/apollo-stack/tutorial-building-a-graphql-server-cddaa023c035#.bu6sdnst4) - Jonas Helfer
-- [Designing Powerful APIs with GraphQL Query Parameters](https://www.graph.cool/docs/tutorials/designing-powerful-apis-with-graphql-query-parameters-aing7uech3/) - Johannes Schickling
-- [GraphQL and the amazing Apollo Client](https://medium.com/google-developer-experts/graphql-and-the-amazing-apollo-client-fe57e162a70c) - Gerard Sans
-- [GraphQL Server Basics (Part I): The Schema](https://www.prisma.io/blog/graphql-server-basics-the-schema-ac5e2950214e) - Nikolas Burk
-- [GraphQL Server Basics (Part II): The Network Layer](https://www.prisma.io/blog/graphql-server-basics-the-network-layer-51d97d21861) - Nikolas Burk
-- [GraphQL Server Basics (Part III): Demystifying the `info` argument in GraphQL resolvers](https://www.prisma.io/blog/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a) - Nikolas Burk
-- [A Beginner’s Guide to GraphQL](https://www.freecodecamp.org/news/a-beginners-guide-to-graphql-86f849ce1bec/) - Leonardo Maldonado
-- [Architecture of a high performance GraphQL to SQL engine](https://blog.hasura.io/architecture-of-a-high-performance-graphql-to-sql-server-58d9944b8a87) - Hasura
diff --git a/src/pages/community/resources/books.mdx b/src/pages/community/resources/books.mdx
deleted file mode 100644
index 6b489c95b6..0000000000
--- a/src/pages/community/resources/books.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
-# Books
-
-- [The GraphQL Guide](https://graphql.guide) by John Resig and Loren Sands-Ramshaw
-- [Learning GraphQL](https://www.amazon.com/Learning-GraphQL-Declarative-Fetching-Modern/dp/1492030716/) by Eve Porcello and Alex Banks
-- [Fullstack GraphQL](https://www.graphqladmin.com/books/fullstack-graphql) by Julian Mayorga
-- [Craft GraphQL APIs in Elixir with Absinthe](https://pragprog.com/titles/wwgraphql/craft-graphql-apis-in-elixir-with-absinthe/) by Bruce Williams and Ben Wilson
-- [Learning GraphQL and Relay](https://www.amazon.com/Learning-GraphQL-Relay-Samer-Buna/dp/1786465752) by Samer Buna
-- [Hands-on Full-Stack Web Development with GraphQL and React](https://www.packtpub.com/en-us/product/hands-on-full-stack-web-development-with-graphql-and-react-9781789135763) by Sebastian Grebe
-- [The Road to GraphQL](https://www.robinwieruch.de/the-road-to-graphql-book/) by Robin Wieruch
-- [Production Ready GraphQL](https://book.productionreadygraphql.com/) by Marc-Andre Giroux
-- [GraphQL Best Practices: Hands-on experience with schema design, security, and error handling for developers](https://www.amazon.com/dp/B0D9H7MJQV) by Artur Czemiel, Nov 2024
diff --git a/src/pages/community/resources/videos.mdx b/src/pages/community/resources/videos.mdx
deleted file mode 100644
index f9a0238554..0000000000
--- a/src/pages/community/resources/videos.mdx
+++ /dev/null
@@ -1,30 +0,0 @@
-# Videos
-
-Developers inside and outside of Facebook have given talks about GraphQL at conferences and meetups around the world. Here are some of our favorites:
-
-- [Exploring GraphQL](https://youtube.com/watch?v=WQLzZf34FJ8) - Lee Byron, React Europe 2015
-- [From Zero to GraphQL in 30 Minutes](https://youtube.com/watch?v=UBGzsb2UkeY) - Steve Luscher
-- [Exploring GraphQL](https://youtube.com/watch?v=_9RgHXqH8J0) - Nick Schrock, @Scale 2015
-- [GraphQL Servers](https://www.youtube.com/watch?v=KOudxKJXsjc) - Nick Schrock, React Rally 2015
-- [GraphQL at Facebook](https://youtube.com/watch?v=etax3aEe2dA) - Dan Schafer, React Europe 2016
-- [GraphQL Source Code Overview](https://youtube.com/watch?v=IqtYr6RX32Q) - Lee Byron
-- [GraphQL Future](https://youtube.com/watch?v=ViXL0YQnioU) - Lee Byron & Laney Kuenzel
-- [Apollo Client: Put GraphQL Data in Your UI](https://www.youtube.com/watch?v=u1E0CbGeICo) - Sashko Stubailo
-- [Relay 2 - simpler, faster, and more predictable](https://www.youtube.com/watch?v=OEfUBN9dAI8) - Greg Hurrell
-- [Build a GraphQL server for Node.js, using PostgreSQL/MySQL](https://www.youtube.com/watch?v=DNPVqK_woRQ) - Lee Benson
-- [A GraphQL Framework for Non-JS Servers](https://www.youtube.com/watch?v=RNoyPSrQyPs) - Syrus Akbary
-- [Modernize Your Angular App with GraphQL](https://www.youtube.com/watch?v=E8feZBidZcs) - Uri Goldshtein, AngularCamp 2016
-- [GraphQL server tutorial for Node.js with SQL, MongoDB and REST ](https://www.youtube.com/watch?v=PHabPhgRUuU) - Jonas Helfer
-- [Building Native Mobile Apps with GraphQL](https://www.youtube.com/watch?v=z5rz3saDPJ8) - Martjin Walraven, React Europe 2016
-- [GraphQL in native applications](https://atscaleconference.com/videos/graphql-in-native-applications-at-scale/) - Igor Canadi & Alex Langenfeld, @Scale 2016
-- [Build a GraphQL Backend with the Serverless Framework](https://acloud.guru/learn/serverless-with-graphql) - Ryan Brown
-- [Build a Full GraphQL Backend in Under 5 Minutes](https://www.youtube.com/watch?v=bJ8pnYd6jPQ) - Michael Paris
-- [GraphQL: From Zero to Scala](https://www.youtube.com/watch?v=6ttypoLyRaU) - Jérémie Astori, Northeast Scala Symposium 2017
-- [GraphQL in Production: Backend as a Service](https://www.youtube.com/watch?v=U2NKoStGBvE) - Michael Paris & Vince Ning, GraphQL in Production Meetup SF August 2016
-- [Development of real-time apps with GraphQL Node.js](https://youtu.be/yh_A6CEqsSM) - Vince Ning & Michael Paris, SF Node Meetup February 2017
-- [Unleashing the power of GraphQL using Angular 2](https://www.youtube.com/watch?v=VYpJ9pfugM8) - Gerard Sans, NG-BE 2016
-- [Webinar Series: GraphQL Around The World](https://graphql-world.com/webinar) - Vince Ning & Michael Paris
-- [All Talks from GraphQL Europe](https://www.youtube.com/playlist?list=PLn2e1F9Rfr6n_WFm9fPE-_wYPrYvSTySt) - Lee Byron, Sashko Stubailo, Dan Schafer, Johannes Schickling and many more
-- [Learning GraphQL with React and Relay](https://www.packtpub.com/application-development/learning-graphql-react-and-relay-video) by Divyendu Singh
-- [Hands-on GraphQL for Better RESTful Web Services (Video)](https://www.packtpub.com/application-development/hands-graphql-better-restful-web-services-video) by Ashwin Hegde
-- [A PostgreSQL backed GraphQL BaaS](https://www.youtube.com/watch?v=neIZcc8y3B0) by Tanmai Gopal
diff --git a/src/pages/community/resources/training-courses.mdx b/src/pages/community/training-courses.mdx
similarity index 100%
rename from src/pages/community/resources/training-courses.mdx
rename to src/pages/community/training-courses.mdx
diff --git a/src/pages/community/resources/vendor-channels.mdx b/src/pages/community/vendor-channels.mdx
similarity index 90%
rename from src/pages/community/resources/vendor-channels.mdx
rename to src/pages/community/vendor-channels.mdx
index f8d8c347e6..1755e5fea7 100644
--- a/src/pages/community/resources/vendor-channels.mdx
+++ b/src/pages/community/vendor-channels.mdx
@@ -3,8 +3,8 @@ import {
ChillicreamIcon,
ApolloIcon,
GraphileIcon,
-} from "../../../icons"
-import { Cards } from '../../../components/cards'
+} from "../../icons"
+import { Cards } from '../../components/cards'
# Vendor Channels
diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx
index c26ab6d58e..a121f17c81 100644
--- a/src/pages/learn/index.mdx
+++ b/src/pages/learn/index.mdx
@@ -11,7 +11,7 @@ import { LearnHeroStripes } from '../../components/learn-aggregator/learn-hero-s
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 { LookingForMore } from "../../components/learn-aggregator/looking-for-more"
+import { LookingForMore } from "../../components/looking-for-more"
-
+
+
diff --git a/src/resources/data.ts b/src/resources/data.ts
new file mode 100644
index 0000000000..db37f4d1b8
--- /dev/null
+++ b/src/resources/data.ts
@@ -0,0 +1,127 @@
+import path from "node:path"
+import { glob } from "node:fs/promises"
+import { readFile } from "node:fs/promises"
+import { cache } from "react"
+import matter from "gray-matter"
+
+import { ResourceMetadata, type ResourceTag, topics } from "./types"
+
+const dataGlob = "src/resources/data/*.json"
+const codeGlob = "src/code/**/*.md"
+const blogGlob = "src/pages/blog/**/*.mdx"
+
+export const readResources = cache(async () => {
+ const resources: ResourceMetadata[] = []
+
+ for await (const file of glob(dataGlob)) {
+ const raw = await readFile(file, "utf8")
+ const parsed = JSON.parse(raw)
+ resources.push(ResourceMetadata.assert(parsed))
+ }
+
+ for await (const file of glob(blogGlob)) {
+ const raw = await readFile(file, "utf8")
+ const { data, content } = matter(raw)
+
+ const title: string | undefined = data.title
+ if (!title) continue
+
+ const slug = blogSlug(file)
+
+ const bodyLines = content
+ .split(/\r?\n/)
+ .map(line => line.trim())
+ .map(line =>
+ line
+ .replace(/!\[[^\]]*\]\([^)]+\)/g, "")
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
+ .replace(/`+/g, "")
+ .replace(/[*_~]+/g, "")
+ .replace(/^#+\s*/, "")
+ .replace(/<\/?[^>]+>/g, "")
+ .trim(),
+ )
+ .filter(line => line.length > 0)
+
+ const excerpt = bodyLines.slice(0, 2).join(" ")
+
+ const description =
+ typeof data.description === "string" && data.description.length > 0
+ ? data.description
+ : excerpt || undefined
+
+ const topicsFromFrontmatter: ResourceTag[] = Array.isArray(data.topics)
+ ? data.topics.filter((tag): tag is ResourceTag =>
+ topics.includes(tag as (typeof topics)[number]),
+ )
+ : []
+
+ const topicTagsFromTags: ResourceTag[] = Array.isArray(data.tags)
+ ? data.tags.filter((tag): tag is ResourceTag =>
+ topics.includes(tag as (typeof topics)[number]),
+ )
+ : []
+
+ const tags: ResourceTag[] = [
+ "blog",
+ ...topicsFromFrontmatter,
+ ...topicTagsFromTags,
+ ]
+
+ resources.push(
+ ResourceMetadata.assert({
+ title,
+ url: slug,
+ author: data.byline,
+ description,
+ kind: "blog",
+ tags,
+ }),
+ )
+ }
+
+ for await (const file of glob(codeGlob)) {
+ const raw = await readFile(file, "utf8")
+ const { data } = matter(raw)
+ const tags: ResourceMetadata["tags"] = Array.isArray(data.tags)
+ ? data.tags
+ : []
+
+ if (!tags.includes("tools-and-libraries")) {
+ tags.push("tools-and-libraries")
+ }
+
+ const url: string | undefined =
+ data.url ??
+ (data.github ? `https://github.com/${data.github}` : undefined) ??
+ (data.npm ? `https://npmjs.com/package/${data.npm}` : undefined)
+
+ const title = data.name ?? path.parse(file).name
+
+ resources.push(
+ ResourceMetadata.assert({
+ title,
+ url,
+ description: data.description,
+ tags,
+ }),
+ )
+ }
+
+ return resources
+})
+
+export async function getResourcesByTag(tag: ResourceTag) {
+ const resources = await readResources()
+ return resources.filter(resource => resource.tags.includes(tag))
+}
+
+function blogSlug(file: string) {
+ const relative = path.relative("src/pages", file)
+ const withoutExt = relative.replace(/\.mdx$/, "")
+ const normalized = withoutExt.split(path.sep).join("/")
+ const clean = normalized.endsWith("/index")
+ ? normalized.slice(0, -"index".length - 1)
+ : normalized
+ return `/${clean}`
+}
diff --git a/src/resources/data/a-beginner-s-guide-to-graphql.json b/src/resources/data/a-beginner-s-guide-to-graphql.json
new file mode 100644
index 0000000000..2552c02efd
--- /dev/null
+++ b/src/resources/data/a-beginner-s-guide-to-graphql.json
@@ -0,0 +1,6 @@
+{
+ "title": "A Beginner’s Guide to GraphQL",
+ "url": "https://www.freecodecamp.org/news/a-beginners-guide-to-graphql-86f849ce1bec/",
+ "author": "Leonardo Maldonado",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/a-graphql-framework-for-non-js-servers-syrus-akbary.json b/src/resources/data/a-graphql-framework-for-non-js-servers-syrus-akbary.json
new file mode 100644
index 0000000000..aac5f9768a
--- /dev/null
+++ b/src/resources/data/a-graphql-framework-for-non-js-servers-syrus-akbary.json
@@ -0,0 +1,7 @@
+{
+ "title": "A GraphQL Framework for Non-JS Servers",
+ "author": "Syrus Akbary",
+ "url": "https://www.youtube.com/watch?v=RNoyPSrQyPs",
+ "tags": ["video", "backend"],
+ "duration": "21:32"
+}
diff --git a/src/resources/data/a-postgresql-backed-graphql-baas.json b/src/resources/data/a-postgresql-backed-graphql-baas.json
new file mode 100644
index 0000000000..eacf30f518
--- /dev/null
+++ b/src/resources/data/a-postgresql-backed-graphql-baas.json
@@ -0,0 +1,7 @@
+{
+ "title": "A PostgreSQL backed GraphQL BaaS",
+ "author": "Tanmai Gopal",
+ "url": "https://www.youtube.com/watch?v=neIZcc8y3B0",
+ "tags": ["video", "backend"],
+ "duration": "14:27"
+}
diff --git a/src/resources/data/all-talks-from-graphql-europe.json b/src/resources/data/all-talks-from-graphql-europe.json
new file mode 100644
index 0000000000..6ab2b1477e
--- /dev/null
+++ b/src/resources/data/all-talks-from-graphql-europe.json
@@ -0,0 +1,5 @@
+{
+ "title": "All Talks from GraphQL Europe",
+ "url": "https://www.youtube.com/playlist?list=PLn2e1F9Rfr6n_WFm9fPE-_wYPrYvSTySt",
+ "tags": ["video", "frontend", "backend"]
+}
diff --git a/src/resources/data/apollo-client-put-graphql-data-in-your-ui.json b/src/resources/data/apollo-client-put-graphql-data-in-your-ui.json
new file mode 100644
index 0000000000..bfa3fdd38f
--- /dev/null
+++ b/src/resources/data/apollo-client-put-graphql-data-in-your-ui.json
@@ -0,0 +1,7 @@
+{
+ "title": "Apollo Client: Put GraphQL Data in Your UI",
+ "author": "Sashko Stubailo",
+ "url": "https://www.youtube.com/watch?v=u1E0CbGeICo",
+ "tags": ["video", "frontend"],
+ "duration": "18:27"
+}
diff --git a/src/resources/data/apollo-odyssey.json b/src/resources/data/apollo-odyssey.json
new file mode 100644
index 0000000000..aa11a294bd
--- /dev/null
+++ b/src/resources/data/apollo-odyssey.json
@@ -0,0 +1,5 @@
+{
+ "title": "Apollo Odyssey",
+ "url": "https://apollographql.com/tutorials",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/apollo-s-blog.json b/src/resources/data/apollo-s-blog.json
new file mode 100644
index 0000000000..e2b5979181
--- /dev/null
+++ b/src/resources/data/apollo-s-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "Apollo's Blog",
+ "url": "https://apollographql.com/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/architecture-of-a-high-performance-graphql-to-sql-engine.json b/src/resources/data/architecture-of-a-high-performance-graphql-to-sql-engine.json
new file mode 100644
index 0000000000..f107cf7911
--- /dev/null
+++ b/src/resources/data/architecture-of-a-high-performance-graphql-to-sql-engine.json
@@ -0,0 +1,6 @@
+{
+ "title": "Architecture of a high performance GraphQL to SQL engine",
+ "url": "https://blog.hasura.io/architecture-of-a-high-performance-graphql-to-sql-server-58d9944b8a87",
+ "author": "Sandip Devarkonda",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/awesome-graphql.json b/src/resources/data/awesome-graphql.json
new file mode 100644
index 0000000000..0befab9e45
--- /dev/null
+++ b/src/resources/data/awesome-graphql.json
@@ -0,0 +1,5 @@
+{
+ "title": "awesome-graphql",
+ "url": "https://github.com/chentsulin/awesome-graphql",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/brand-guidelines.json b/src/resources/data/brand-guidelines.json
new file mode 100644
index 0000000000..f32f7804f8
--- /dev/null
+++ b/src/resources/data/brand-guidelines.json
@@ -0,0 +1,5 @@
+{
+ "title": "brand guidelines",
+ "url": "/brand",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/build-a-full-graphql-backend-in-under-5-minutes-michael-paris.json b/src/resources/data/build-a-full-graphql-backend-in-under-5-minutes-michael-paris.json
new file mode 100644
index 0000000000..7fc5936027
--- /dev/null
+++ b/src/resources/data/build-a-full-graphql-backend-in-under-5-minutes-michael-paris.json
@@ -0,0 +1,7 @@
+{
+ "title": "Build a Full GraphQL Backend in Under 5 Minutes",
+ "author": "Michael Paris",
+ "url": "https://www.youtube.com/watch?v=bJ8pnYd6jPQ",
+ "tags": ["video", "backend"],
+ "duration": "4:55"
+}
diff --git a/src/resources/data/build-a-graphql-server-for-node-js-using-postgresql-mysql-lee-benson.json b/src/resources/data/build-a-graphql-server-for-node-js-using-postgresql-mysql-lee-benson.json
new file mode 100644
index 0000000000..d48a5744c9
--- /dev/null
+++ b/src/resources/data/build-a-graphql-server-for-node-js-using-postgresql-mysql-lee-benson.json
@@ -0,0 +1,7 @@
+{
+ "title": "Build a GraphQL server for Node.js, using PostgreSQL/MySQL",
+ "author": "Lee Benson",
+ "url": "https://www.youtube.com/watch?v=DNPVqK_woRQ",
+ "tags": ["video", "backend"],
+ "duration": "45:04"
+}
diff --git a/src/resources/data/building-native-mobile-apps-with-graphql-martjin-walraven-react-europe-2016.json b/src/resources/data/building-native-mobile-apps-with-graphql-martjin-walraven-react-europe-2016.json
new file mode 100644
index 0000000000..948a1ff738
--- /dev/null
+++ b/src/resources/data/building-native-mobile-apps-with-graphql-martjin-walraven-react-europe-2016.json
@@ -0,0 +1,7 @@
+{
+ "title": "Building Native Mobile Apps with GraphQL",
+ "author": "Martjin Walraven",
+ "url": "https://www.youtube.com/watch?v=z5rz3saDPJ8",
+ "tags": ["video", "frontend"],
+ "duration": "23:55"
+}
diff --git a/src/resources/data/building-the-f8-app-using-graphql-relay.json b/src/resources/data/building-the-f8-app-using-graphql-relay.json
new file mode 100644
index 0000000000..3c36df9045
--- /dev/null
+++ b/src/resources/data/building-the-f8-app-using-graphql-relay.json
@@ -0,0 +1,5 @@
+{
+ "title": "Building the f8 App: Using GraphQL & Relay",
+ "url": "http://makeitopen.com/docs/en/1-A2-relay.html",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/chillicream-s-blog.json b/src/resources/data/chillicream-s-blog.json
new file mode 100644
index 0000000000..68a2657d38
--- /dev/null
+++ b/src/resources/data/chillicream-s-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "ChilliCream's Blog",
+ "url": "https://chillicream.com/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/community-events-section.json b/src/resources/data/community-events-section.json
new file mode 100644
index 0000000000..2c3af619b8
--- /dev/null
+++ b/src/resources/data/community-events-section.json
@@ -0,0 +1,5 @@
+{
+ "title": "community events section",
+ "url": "/community/upcoming-events/#meetups",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/craft-graphql-apis-in-elixir-with-absinthe.json b/src/resources/data/craft-graphql-apis-in-elixir-with-absinthe.json
new file mode 100644
index 0000000000..b8c5cf6344
--- /dev/null
+++ b/src/resources/data/craft-graphql-apis-in-elixir-with-absinthe.json
@@ -0,0 +1,6 @@
+{
+ "title": "Craft GraphQL APIs in Elixir with Absinthe",
+ "url": "https://pragprog.com/titles/wwgraphql/craft-graphql-apis-in-elixir-with-absinthe/",
+ "author": "Bruce Williams & Ben Wilson",
+ "tags": ["book"]
+}
diff --git a/src/resources/data/designing-powerful-apis-with-graphql-query-parameters.json b/src/resources/data/designing-powerful-apis-with-graphql-query-parameters.json
new file mode 100644
index 0000000000..d3f99c4a56
--- /dev/null
+++ b/src/resources/data/designing-powerful-apis-with-graphql-query-parameters.json
@@ -0,0 +1,5 @@
+{
+ "title": "Designing Powerful APIs with GraphQL Query Parameters",
+ "url": "https://www.graph.cool/docs/tutorials/designing-powerful-apis-with-graphql-query-parameters-aing7uech3/",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/dev-to-graphql-tag.json b/src/resources/data/dev-to-graphql-tag.json
new file mode 100644
index 0000000000..7ce2241769
--- /dev/null
+++ b/src/resources/data/dev-to-graphql-tag.json
@@ -0,0 +1,5 @@
+{
+ "title": "DEV.to GraphQL tag",
+ "url": "https://dev.to/t/graphql",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/development-of-real-time-apps-with-graphql-node-js-vince-ning-michael-paris-sf-node-meetup-february-2017.json b/src/resources/data/development-of-real-time-apps-with-graphql-node-js-vince-ning-michael-paris-sf-node-meetup-february-2017.json
new file mode 100644
index 0000000000..b8d5ed3bce
--- /dev/null
+++ b/src/resources/data/development-of-real-time-apps-with-graphql-node-js-vince-ning-michael-paris-sf-node-meetup-february-2017.json
@@ -0,0 +1,7 @@
+{
+ "title": "Development of real-time apps with GraphQL Node.js",
+ "author": "Vince Ning & Michael Paris",
+ "url": "https://youtu.be/yh_A6CEqsSM",
+ "tags": ["video", "backend"],
+ "duration": "22:33"
+}
diff --git a/src/resources/data/escape-security-blog.json b/src/resources/data/escape-security-blog.json
new file mode 100644
index 0000000000..a0190d21a3
--- /dev/null
+++ b/src/resources/data/escape-security-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "Escape Security Blog",
+ "url": "https://escape.tech/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/exploring-graphql.json b/src/resources/data/exploring-graphql.json
new file mode 100644
index 0000000000..1729969bb2
--- /dev/null
+++ b/src/resources/data/exploring-graphql.json
@@ -0,0 +1,7 @@
+{
+ "title": "Exploring GraphQL",
+ "url": "https://youtube.com/watch?v=WQLzZf34FJ8",
+ "author": "Lee Byron",
+ "tags": ["video"],
+ "duration": "27:18"
+}
diff --git a/src/resources/data/from-rest-to-graphql.json b/src/resources/data/from-rest-to-graphql.json
new file mode 100644
index 0000000000..b672e423aa
--- /dev/null
+++ b/src/resources/data/from-rest-to-graphql.json
@@ -0,0 +1,6 @@
+{
+ "title": "From REST to GraphQL",
+ "url": "https://0x2a.sh/from-rest-to-graphql-b4e95e94c26b#.tag7nzkrb",
+ "author": "Garen J. Torikian",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/from-zero-to-graphql-in-30-minutes.json b/src/resources/data/from-zero-to-graphql-in-30-minutes.json
new file mode 100644
index 0000000000..3460116995
--- /dev/null
+++ b/src/resources/data/from-zero-to-graphql-in-30-minutes.json
@@ -0,0 +1,7 @@
+{
+ "title": "From Zero to GraphQL in 30 Minutes",
+ "url": "https://youtube.com/watch?v=UBGzsb2UkeY",
+ "author": "Steven Luscher",
+ "tags": ["video"],
+ "duration": "30:13"
+}
diff --git a/src/resources/data/fullstack-graphql.json b/src/resources/data/fullstack-graphql.json
new file mode 100644
index 0000000000..0f163bf5ec
--- /dev/null
+++ b/src/resources/data/fullstack-graphql.json
@@ -0,0 +1,6 @@
+{
+ "title": "Fullstack GraphQL",
+ "url": "https://www.graphqladmin.com/books/fullstack-graphql",
+ "author": "Julian Mayorga",
+ "tags": ["book"]
+}
diff --git a/src/resources/data/graphql-and-the-amazing-apollo-client.json b/src/resources/data/graphql-and-the-amazing-apollo-client.json
new file mode 100644
index 0000000000..e74ff64ec1
--- /dev/null
+++ b/src/resources/data/graphql-and-the-amazing-apollo-client.json
@@ -0,0 +1,6 @@
+{
+ "title": "GraphQL and the amazing Apollo Client",
+ "url": "https://medium.com/google-developer-experts/graphql-and-the-amazing-apollo-client-fe57e162a70c",
+ "author": "Gerard Sans",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/graphql-apis.json b/src/resources/data/graphql-apis.json
new file mode 100644
index 0000000000..6c7365fdae
--- /dev/null
+++ b/src/resources/data/graphql-apis.json
@@ -0,0 +1,5 @@
+{
+ "title": "graphql-apis",
+ "url": "https://github.com/APIs-guru/graphql-apis",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/graphql-at-facebook.json b/src/resources/data/graphql-at-facebook.json
new file mode 100644
index 0000000000..ab864678b8
--- /dev/null
+++ b/src/resources/data/graphql-at-facebook.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL at Facebook",
+ "url": "https://youtube.com/watch?v=etax3aEe2dA",
+ "author": "Dan Schafer",
+ "tags": ["video"],
+ "duration": "26:30"
+}
diff --git a/src/resources/data/graphql-best-practices-hands-on-experience-with-schema-design-security-and-error-handling-for-developers.json b/src/resources/data/graphql-best-practices-hands-on-experience-with-schema-design-security-and-error-handling-for-developers.json
new file mode 100644
index 0000000000..c5fba326c9
--- /dev/null
+++ b/src/resources/data/graphql-best-practices-hands-on-experience-with-schema-design-security-and-error-handling-for-developers.json
@@ -0,0 +1,6 @@
+{
+ "title": "GraphQL Best Practices: Hands-on experience with schema design, security, and error handling for developers",
+ "url": "https://www.amazon.com/dp/B0D9H7MJQV",
+ "author": "Marc-André Giroux & Apoorva Pandey",
+ "tags": ["book"]
+}
diff --git a/src/resources/data/graphql-code-of-conduct.json b/src/resources/data/graphql-code-of-conduct.json
new file mode 100644
index 0000000000..64d708b1d2
--- /dev/null
+++ b/src/resources/data/graphql-code-of-conduct.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL Code of Conduct",
+ "url": "/codeofconduct/",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/graphql-concepts-visualized.json b/src/resources/data/graphql-concepts-visualized.json
new file mode 100644
index 0000000000..0e8e235f89
--- /dev/null
+++ b/src/resources/data/graphql-concepts-visualized.json
@@ -0,0 +1,6 @@
+{
+ "title": "GraphQL Concepts Visualized",
+ "url": "https://medium.com/apollo-stack/the-concepts-of-graphql-bc68bd819be3#.hfczgtdsj",
+ "author": "Dhaivat Pandya",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/graphql-editor-blog.json b/src/resources/data/graphql-editor-blog.json
new file mode 100644
index 0000000000..e178be9bcc
--- /dev/null
+++ b/src/resources/data/graphql-editor-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL Editor Blog",
+ "url": "https://blog.graphqleditor.com",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/graphql-explained.json b/src/resources/data/graphql-explained.json
new file mode 100644
index 0000000000..8f969374d4
--- /dev/null
+++ b/src/resources/data/graphql-explained.json
@@ -0,0 +1,6 @@
+{
+ "title": "GraphQL Explained",
+ "url": "https://medium.com/apollo-stack/graphql-explained-5844742f195e#.zdykxos6i",
+ "author": "JH",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/graphql-from-zero-to-scala.json b/src/resources/data/graphql-from-zero-to-scala.json
new file mode 100644
index 0000000000..16794d200c
--- /dev/null
+++ b/src/resources/data/graphql-from-zero-to-scala.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL: From Zero to Scala",
+ "author": "Jérémie Astori",
+ "url": "https://www.youtube.com/watch?v=6ttypoLyRaU",
+ "tags": ["video", "backend"],
+ "duration": "15:31"
+}
diff --git a/src/resources/data/graphql-future.json b/src/resources/data/graphql-future.json
new file mode 100644
index 0000000000..34e0edabf9
--- /dev/null
+++ b/src/resources/data/graphql-future.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL Future",
+ "url": "https://youtube.com/watch?v=ViXL0YQnioU",
+ "author": "Lee Byron",
+ "tags": ["video"],
+ "duration": "32:18"
+}
diff --git a/src/resources/data/graphql-in-native-applications.json b/src/resources/data/graphql-in-native-applications.json
new file mode 100644
index 0000000000..18112cdf2b
--- /dev/null
+++ b/src/resources/data/graphql-in-native-applications.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL in native applications",
+ "author": "Igor Canadi & Alex Langenfeld",
+ "url": "https://atscaleconference.com/videos/graphql-in-native-applications-at-scale/",
+ "tags": ["video", "frontend"],
+ "duration": "26:15"
+}
diff --git a/src/resources/data/graphql-in-production-backend-as-a-service-michael-paris-vince-ning-graphql-in-production-meetup-sf-august-2016.json b/src/resources/data/graphql-in-production-backend-as-a-service-michael-paris-vince-ning-graphql-in-production-meetup-sf-august-2016.json
new file mode 100644
index 0000000000..e4500dbfcd
--- /dev/null
+++ b/src/resources/data/graphql-in-production-backend-as-a-service-michael-paris-vince-ning-graphql-in-production-meetup-sf-august-2016.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL in Production: Backend as a Service",
+ "author": "Michael Paris & Vince Ning",
+ "url": "https://www.youtube.com/watch?v=U2NKoStGBvE",
+ "tags": ["video", "backend"],
+ "duration": "19:08"
+}
diff --git a/src/resources/data/graphql-js-tutorial.json b/src/resources/data/graphql-js-tutorial.json
new file mode 100644
index 0000000000..8ad1d6af05
--- /dev/null
+++ b/src/resources/data/graphql-js-tutorial.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL-JS tutorial",
+ "url": "/graphql-js",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/graphql-screencasts.json b/src/resources/data/graphql-screencasts.json
new file mode 100644
index 0000000000..7f21b01ad3
--- /dev/null
+++ b/src/resources/data/graphql-screencasts.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL Screencasts",
+ "url": "https://graphql.wtf",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/graphql-server-tutorial-for-node-js-with-sql-mongodb-and-rest-jonas-helfer.json b/src/resources/data/graphql-server-tutorial-for-node-js-with-sql-mongodb-and-rest-jonas-helfer.json
new file mode 100644
index 0000000000..9ba61ed60f
--- /dev/null
+++ b/src/resources/data/graphql-server-tutorial-for-node-js-with-sql-mongodb-and-rest-jonas-helfer.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL server tutorial for Node.js with SQL, MongoDB and REST",
+ "author": "Jonas Helfer",
+ "url": "https://www.youtube.com/watch?v=PHabPhgRUuU",
+ "tags": ["video", "backend"],
+ "duration": "1:03:01"
+}
diff --git a/src/resources/data/graphql-servers.json b/src/resources/data/graphql-servers.json
new file mode 100644
index 0000000000..95b1b633b3
--- /dev/null
+++ b/src/resources/data/graphql-servers.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL Servers",
+ "author": "Nick Schrock",
+ "url": "https://www.youtube.com/watch?v=KOudxKJXsjc",
+ "tags": ["video", "backend"],
+ "duration": "28:03"
+}
diff --git a/src/resources/data/graphql-source-code-overview.json b/src/resources/data/graphql-source-code-overview.json
new file mode 100644
index 0000000000..bc2f659367
--- /dev/null
+++ b/src/resources/data/graphql-source-code-overview.json
@@ -0,0 +1,7 @@
+{
+ "title": "GraphQL Source Code Overview",
+ "author": "Lee Byron",
+ "url": "https://youtube.com/watch?v=IqtYr6RX32Q",
+ "tags": ["video", "backend"],
+ "duration": "25:32"
+}
diff --git a/src/resources/data/graphql-tutorials.json b/src/resources/data/graphql-tutorials.json
new file mode 100644
index 0000000000..994d2ff091
--- /dev/null
+++ b/src/resources/data/graphql-tutorials.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL Tutorials",
+ "url": "https://hasura.io/learn",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/graphql-weekly.json b/src/resources/data/graphql-weekly.json
new file mode 100644
index 0000000000..2d90509692
--- /dev/null
+++ b/src/resources/data/graphql-weekly.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL Weekly",
+ "url": "https://graphqlweekly.com",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/graphql-wtf-episodes-feed.json b/src/resources/data/graphql-wtf-episodes-feed.json
new file mode 100644
index 0000000000..f59eceabdb
--- /dev/null
+++ b/src/resources/data/graphql-wtf-episodes-feed.json
@@ -0,0 +1,5 @@
+{
+ "title": "GraphQL WTF Episodes Feed",
+ "url": "https://graphql.wtf",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/hands-on-full-stack-web-development-with-graphql-and-react.json b/src/resources/data/hands-on-full-stack-web-development-with-graphql-and-react.json
new file mode 100644
index 0000000000..57c9172b6b
--- /dev/null
+++ b/src/resources/data/hands-on-full-stack-web-development-with-graphql-and-react.json
@@ -0,0 +1,6 @@
+{
+ "title": "Hands-on Full-Stack Web Development with GraphQL and React",
+ "url": "https://www.packtpub.com/en-us/product/hands-on-full-stack-web-development-with-graphql-and-react-9781789135763",
+ "author": "Sebastian Grebe",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/hasura-s-blog.json b/src/resources/data/hasura-s-blog.json
new file mode 100644
index 0000000000..7addc43662
--- /dev/null
+++ b/src/resources/data/hasura-s-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "Hasura's Blog",
+ "url": "https://hasura.io/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/inigo-s-security-blog.json b/src/resources/data/inigo-s-security-blog.json
new file mode 100644
index 0000000000..ef9f0f1c82
--- /dev/null
+++ b/src/resources/data/inigo-s-security-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "Inigo's Security Blog",
+ "url": "https://inigo.io/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/learning-graphql-and-relay.json b/src/resources/data/learning-graphql-and-relay.json
new file mode 100644
index 0000000000..a5b131f8f9
--- /dev/null
+++ b/src/resources/data/learning-graphql-and-relay.json
@@ -0,0 +1,6 @@
+{
+ "title": "Learning GraphQL and Relay",
+ "url": "https://www.amazon.com/Learning-GraphQL-Relay-Samer-Buna/dp/1786465752",
+ "author": "Samer Buna",
+ "tags": ["book"]
+}
diff --git a/src/resources/data/learning-graphql.json b/src/resources/data/learning-graphql.json
new file mode 100644
index 0000000000..ee063bd648
--- /dev/null
+++ b/src/resources/data/learning-graphql.json
@@ -0,0 +1,6 @@
+{
+ "title": "Learning GraphQL",
+ "url": "https://www.amazon.com/Learning-GraphQL-Declarative-Fetching-Modern/dp/1492030716/",
+ "author": "Eve Porcello & Alex Banks",
+ "tags": ["book"]
+}
diff --git a/src/resources/data/modernize-your-angular-app-with-graphql.json b/src/resources/data/modernize-your-angular-app-with-graphql.json
new file mode 100644
index 0000000000..e62c2b7c82
--- /dev/null
+++ b/src/resources/data/modernize-your-angular-app-with-graphql.json
@@ -0,0 +1,7 @@
+{
+ "title": "Modernize Your Angular App with GraphQL",
+ "author": "Uri Goldshtein",
+ "url": "https://www.youtube.com/watch?v=E8feZBidZcs",
+ "tags": ["video", "frontend"],
+ "duration": "37:38"
+}
diff --git a/src/resources/data/official-graphql-blog.json b/src/resources/data/official-graphql-blog.json
new file mode 100644
index 0000000000..63976c18d7
--- /dev/null
+++ b/src/resources/data/official-graphql-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "Official GraphQL Blog",
+ "url": "https://graphql.org/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/production-ready-graphql.json b/src/resources/data/production-ready-graphql.json
new file mode 100644
index 0000000000..48022997b1
--- /dev/null
+++ b/src/resources/data/production-ready-graphql.json
@@ -0,0 +1,6 @@
+{
+ "title": "Production Ready GraphQL",
+ "url": "https://book.productionreadygraphql.com/",
+ "author": "Marc-Andre Giroux",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/relay-2-simpler-faster-and-more-predictable-greg-hurrell.json b/src/resources/data/relay-2-simpler-faster-and-more-predictable-greg-hurrell.json
new file mode 100644
index 0000000000..f0a6960ed5
--- /dev/null
+++ b/src/resources/data/relay-2-simpler-faster-and-more-predictable-greg-hurrell.json
@@ -0,0 +1,7 @@
+{
+ "title": "Relay 2 - simpler, faster, and more predictable",
+ "author": "Greg Hurrell",
+ "url": "https://www.youtube.com/watch?v=OEfUBN9dAI8",
+ "tags": ["video", "frontend", "backend"],
+ "duration": "1:26:01"
+}
diff --git a/src/resources/data/relicensing-the-graphql-specification.json b/src/resources/data/relicensing-the-graphql-specification.json
new file mode 100644
index 0000000000..334cfdf4c0
--- /dev/null
+++ b/src/resources/data/relicensing-the-graphql-specification.json
@@ -0,0 +1,6 @@
+{
+ "title": "Relicensing the GraphQL specification",
+ "url": "https://medium.com/@leeb/relicensing-the-graphql-specification-e7d07a52301b",
+ "author": "Lee Byron",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/stepzen-s-blog.json b/src/resources/data/stepzen-s-blog.json
new file mode 100644
index 0000000000..208aca0ebb
--- /dev/null
+++ b/src/resources/data/stepzen-s-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "StepZen's Blog",
+ "url": "https://stepzen.com/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/the-graphql-guide.json b/src/resources/data/the-graphql-guide.json
new file mode 100644
index 0000000000..b34d66f420
--- /dev/null
+++ b/src/resources/data/the-graphql-guide.json
@@ -0,0 +1,6 @@
+{
+ "title": "The GraphQL Guide",
+ "url": "https://graphql.guide",
+ "author": "Loren Sands-Ramshaw",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/the-guild-s-blog.json b/src/resources/data/the-guild-s-blog.json
new file mode 100644
index 0000000000..461761c85b
--- /dev/null
+++ b/src/resources/data/the-guild-s-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "The Guild's Blog",
+ "url": "https://the-guild.dev/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/the-guild-s-newsletter.json b/src/resources/data/the-guild-s-newsletter.json
new file mode 100644
index 0000000000..c34b24e874
--- /dev/null
+++ b/src/resources/data/the-guild-s-newsletter.json
@@ -0,0 +1,5 @@
+{
+ "title": "The Guild's Newsletter",
+ "url": "https://getrevue.co/profile/TheGuild",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/the-road-to-graphql.json b/src/resources/data/the-road-to-graphql.json
new file mode 100644
index 0000000000..a9a97f091f
--- /dev/null
+++ b/src/resources/data/the-road-to-graphql.json
@@ -0,0 +1,6 @@
+{
+ "title": "The Road to GraphQL",
+ "url": "https://www.robinwieruch.de/the-road-to-graphql-book/",
+ "author": "Robin Wieruch",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/trademark-policy.json b/src/resources/data/trademark-policy.json
new file mode 100644
index 0000000000..c51132fd8e
--- /dev/null
+++ b/src/resources/data/trademark-policy.json
@@ -0,0 +1,5 @@
+{
+ "title": "Linux Foundation Trademark Policy",
+ "url": "https://lfprojects.org/policies/trademark-policy/",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/tutorial-how-to-build-a-graphql-server.json b/src/resources/data/tutorial-how-to-build-a-graphql-server.json
new file mode 100644
index 0000000000..270598c7f5
--- /dev/null
+++ b/src/resources/data/tutorial-how-to-build-a-graphql-server.json
@@ -0,0 +1,6 @@
+{
+ "title": "Tutorial: How to Build a GraphQL Server",
+ "url": "https://medium.com/apollo-stack/tutorial-building-a-graphql-server-cddaa023c035#.bu6sdnst4",
+ "author": "Jonas Helfer & Johanna Griffin",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/tutorial-kick-start-a-js-api-with-apollo-server-dataloader-and-knex.json b/src/resources/data/tutorial-kick-start-a-js-api-with-apollo-server-dataloader-and-knex.json
new file mode 100644
index 0000000000..48eaef09bb
--- /dev/null
+++ b/src/resources/data/tutorial-kick-start-a-js-api-with-apollo-server-dataloader-and-knex.json
@@ -0,0 +1,6 @@
+{
+ "title": "Tutorial: Kick start a JS API with Apollo-server, Dataloader and Knex",
+ "url": "https://bamtech.gitbook.io/dev-standards/backend/graphql-js/getting-started-with-apollo-server-dataloader-knex.mo",
+ "author": "Thomas Pucci",
+ "tags": ["blog"]
+}
diff --git a/src/resources/data/unleashing-the-power-of-graphql-using-angular-2-gerard-sans-ng-be-2016.json b/src/resources/data/unleashing-the-power-of-graphql-using-angular-2-gerard-sans-ng-be-2016.json
new file mode 100644
index 0000000000..0da38a9a87
--- /dev/null
+++ b/src/resources/data/unleashing-the-power-of-graphql-using-angular-2-gerard-sans-ng-be-2016.json
@@ -0,0 +1,7 @@
+{
+ "title": "Unleashing the power of GraphQL using Angular 2",
+ "author": "Gerard Sans",
+ "url": "https://www.youtube.com/watch?v=VYpJ9pfugM8",
+ "tags": ["video", "frontend"],
+ "duration": "45:35"
+}
diff --git a/src/resources/data/wundergraph-s-blog.json b/src/resources/data/wundergraph-s-blog.json
new file mode 100644
index 0000000000..645953db5d
--- /dev/null
+++ b/src/resources/data/wundergraph-s-blog.json
@@ -0,0 +1,5 @@
+{
+ "title": "WunderGraph's Blog",
+ "url": "https://wundergraph.com/blog",
+ "tags": ["blog-or-newsletter"]
+}
diff --git a/src/resources/data/yoga-graphql-server-tutorial.json b/src/resources/data/yoga-graphql-server-tutorial.json
new file mode 100644
index 0000000000..c1bf2f20ae
--- /dev/null
+++ b/src/resources/data/yoga-graphql-server-tutorial.json
@@ -0,0 +1,5 @@
+{
+ "title": "Yoga GraphQL Server Tutorial",
+ "url": "https://the-guild.dev/graphql/yoga-server/tutorial",
+ "tags": ["guide"]
+}
diff --git a/src/resources/data/your-first-graphql-server.json b/src/resources/data/your-first-graphql-server.json
new file mode 100644
index 0000000000..0af9082ceb
--- /dev/null
+++ b/src/resources/data/your-first-graphql-server.json
@@ -0,0 +1,6 @@
+{
+ "title": "Your First GraphQL Server",
+ "url": "https://medium.com/the-graphqlhub/your-first-graphql-server-3c766ab4f0a2#.ovn0y19k4",
+ "author": "Clay Allsopp",
+ "tags": ["blog"]
+}
diff --git a/src/resources/types.ts b/src/resources/types.ts
new file mode 100644
index 0000000000..8692a5d553
--- /dev/null
+++ b/src/resources/types.ts
@@ -0,0 +1,38 @@
+import { tagColors } from "@/app/conf/_design-system/tag-colors"
+import { type } from "arktype"
+
+export const topics = [
+ "frontend",
+ "backend",
+ "federation",
+ "security",
+ "ai",
+ "monitoring",
+] as const
+export type Topic = (typeof topics)[number]
+
+export const kinds = [
+ "video",
+ "blog",
+ "tools-and-libraries",
+ "guide",
+ "book",
+ "blog-or-newsletter",
+ "docs",
+] as const
+export type Kind = (typeof kinds)[number]
+
+export type ResourceTag = Topic | Kind
+
+export const ResourceMetadata = type({
+ title: "string>0",
+ url: type("string.url").or("/^\\/.+$/"),
+ "author?": "string",
+ "kind?": type.enumerated(...kinds),
+ "topics?": type.enumerated(...topics).array(),
+ "description?": "string>0",
+ "duration?": "string",
+ tags: type.enumerated(...Object.keys(tagColors)).array(),
+})
+
+export type ResourceMetadata = typeof ResourceMetadata.inferOut
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 16649f5949..1dbf34a0fe 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -128,9 +128,10 @@ const config: Config = {
plugin(({ addBase }) => {
// heading styles
addBase({
- ".typography-d1, .typography-h1, .typography-h2, .typography-h3": {
- lineHeight: "1.2",
- },
+ ".typography-d1, .typography-h1, .typography-h2, .typography-h3, .typography-h4":
+ {
+ lineHeight: "1.2",
+ },
".typography-d1": {
fontSize: "48px",
"@screen lg": {
@@ -155,6 +156,12 @@ const config: Config = {
fontSize: "32px",
},
},
+ ".typography-h4": {
+ fontSize: "20px",
+ "@screen md": {
+ fontSize: "28px",
+ },
+ },
})
// paragraph styles
diff --git a/test/e2e/resources-hub.spec.ts b/test/e2e/resources-hub.spec.ts
new file mode 100644
index 0000000000..bc1816f630
--- /dev/null
+++ b/test/e2e/resources-hub.spec.ts
@@ -0,0 +1,24 @@
+import { expect, test } from "@playwright/test"
+
+const pages = [
+ "/resources",
+ "/resources/frontend",
+ "/resources/backend",
+ "/resources/federation",
+ "/resources/ai",
+ "/resources/security",
+ "/resources/monitoring",
+ "/code",
+ "/conf",
+ "/resources/reading",
+ "/resources/video",
+]
+
+test.describe("Resource hub pages exist", () => {
+ for (const path of pages) {
+ test(`renders ${path}`, async ({ page }) => {
+ const response = await page.goto(path)
+ expect(response?.ok()).toBeTruthy()
+ })
+ }
+})
diff --git a/vercel.json b/vercel.json
index 244e7c6f2c..a0e09efea4 100644
--- a/vercel.json
+++ b/vercel.json
@@ -482,7 +482,12 @@
},
{
"source": "/community",
- "destination": "/community/resources/official-channels",
+ "destination": "/community/official-channels",
+ "permanent": true
+ },
+ {
+ "source": "/community/",
+ "destination": "/community/official-channels/",
"permanent": true
},
{
@@ -495,6 +500,46 @@
"destination": "/community/contribute/essential-links",
"permanent": true
},
+ {
+ "source": "/community/resources/official-channels",
+ "destination": "/community/official-channels",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/training-courses",
+ "destination": "/community/training-courses",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/community-channels",
+ "destination": "/community/community-channels",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/vendor-channels",
+ "destination": "/community/vendor-channels",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/more-resources",
+ "destination": "/community/more-resources",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/blogs-and-newsletters",
+ "destination": "/resources/reading/blogs-and-newsletters",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/video",
+ "destination": "/resources/video",
+ "permanent": true
+ },
+ {
+ "source": "/community/resources/books",
+ "destination": "/resources/reading/books",
+ "permanent": true
+ },
{
"source": "/conf/",
"destination": "/conf/2025/",
@@ -557,12 +602,12 @@
},
{
"source": "/community",
- "destination": "/community/resources/official-channels/",
+ "destination": "/community/official-channels/",
"permanent": true
},
{
"source": "/community/",
- "destination": "/community/resources/official-channels/",
+ "destination": "/community/official-channels/",
"permanent": true
},
{