-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocusaurus.config.js
352 lines (337 loc) · 11.6 KB
/
docusaurus.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
// eslint-disable-next-line @typescript-eslint/no-var-requires
const lightCodeTheme = require("prism-react-renderer/themes/github");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const darkCodeTheme = require("./src/theme/prism-theme/oneDark");
// Load environment variables.
require("dotenv").config({ path: ".env.local" });
const ENTRY_POINTS_TO_DOCUMENT = [
"browser",
"server",
"react",
"react-auth0",
"react-clerk",
"nextjs",
"values",
];
/** @type {import('@docusaurus/types').Config} */
const config = {
title: "Convex Developer Hub",
tagline: "The source for documentation about Convex.",
url: "https://docs.convex.dev",
baseUrl: "/",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "throw",
favicon: "img/favicon.ico",
organizationName: "get-convex", // Usually your GitHub org/user name.
projectName: "Convex", // Usually your repo name.
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans".
i18n: {
defaultLocale: "en",
locales: ["en"],
},
customFields: {
// Make these environment variables available to the docs site.
KAPA_AI_PROJECT: process.env.KAPA_AI_PROJECT,
KAPA_AI_KEY: process.env.KAPA_AI_KEY,
},
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
{
// Replace with your project's social card
// image: "img/docusaurus-social-card.jpg", // TODO!
docs: {
sidebar: {
hideable: false,
autoCollapseCategories: true,
},
},
navbar: {
hideOnScroll: true,
logo: {
href: "https://convex.dev",
alt: "Convex",
src: "img/convex-light.svg",
srcDark: "img/convex-dark.svg",
},
items: [
{
type: "docSidebar",
position: "left",
// If you change this make sure to update
// src/theme/DocSidebar/Desktop/index.js
// home link
sidebarId: "docs",
label: "docs",
},
{
type: "custom-convex-search",
position: "left",
},
{
type: "custom-convex-ai-chat",
position: "left",
},
{
href: "https://stack.convex.dev/",
label: "Stack",
position: "right",
},
{
href: "https://convex.dev/releases",
label: "Releases",
position: "right",
},
{
href: "https://github.com/get-convex",
label: "Examples",
position: "right",
className: "convex-github-logo convex-icon-link",
},
{
href: "https://convex.dev/community",
label: "Discord",
position: "right",
className: "convex-discord-logo convex-icon-link",
},
],
},
footer: {
links: [
{
label: "GitHub",
href: "https://github.com/get-convex",
className: "convex-github-logo convex-icon-link",
},
{
label: "Discord",
to: "https://convex.dev/community",
className: "convex-discord-logo convex-icon-link",
},
{
label: "Twitter",
href: "https://twitter.com/convex_dev",
className: "convex-twitter-logo convex-icon-link",
},
],
copyright: `Copyright © ${new Date().getFullYear()} Convex, Inc.`,
},
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
additionalLanguages: ["rust", "kotlin", "swift"],
},
image: "img/social.png",
metadata: [
{ name: "twitter:card", content: "summary_large_image" },
{ name: "twitter:image:alt", content: "Convex Docs logo" },
{ name: "og:image:alt", content: "Convex Docs logo" },
],
},
themes: ["mdx-v2"],
presets: [
[
"classic",
/** @type {import('@docusaurus/preset-classic').Options} */
({
gtag: {
trackingID: "G-BE1B7P7T72",
},
docs: {
sidebarPath: require.resolve("./sidebars.js"),
routeBasePath: "/",
async sidebarItemsGenerator({
defaultSidebarItemsGenerator,
...args
}) {
const originalSidebarItems =
await defaultSidebarItemsGenerator(args);
// Remove "API" and "Generated Code" from the main sidebar because
// they have their own tab.
if (
args.item.type === "autogenerated" &&
args.item.dirName === "."
) {
const finalSidebarItems = originalSidebarItems.filter(
(item) =>
!("label" in item) ||
(item.label !== "API" &&
item.label !== "Generated Code" &&
item.label !== "HTTP API"),
);
return finalSidebarItems;
}
// Drop `index.md` from "Generated Code" because it's already included
// as the category index and Docusaurus is dumb and adds it twice.
if (
args.item.type === "autogenerated" &&
args.item.dirName === "generated-api"
) {
return originalSidebarItems.filter(
(item) => !("id" in item) || item.id !== "generated-api/index",
);
}
// If we have other autogenerated items, don't touch them.
if (
args.item.type === "autogenerated" &&
args.item.dirName !== "api"
) {
return originalSidebarItems;
}
/**
* Custom generator for api sidebar items.
*
* We have a custom generator for the items in the sidebar because
* we reorganize the API docs that docusaurus-plugin-typedoc generates.
*
* The original scheme is:
* - API Reference
* - Modules
* - One item per entry point
* - Interfaces
* - All the interfaces for all the entry points
* - Classes
* - All the classes for all the entry points
*
* We reorganize that into:
* - API Reference
* - convex/$entryPoint
* - classes, interfaces for $entrypoint
* - Generated Code
* - generated hooks and types.
*/
const entryPointToItems = {};
for (const entryPoint of ENTRY_POINTS_TO_DOCUMENT) {
entryPointToItems[entryPoint] = [];
}
for (const category of originalSidebarItems) {
// Skip the "Table of contents" category because we don't need
// it, the "Modules" category because we create that ourselves
// below, and "Readme" because it's already in sidebars.js.
// The rest are things like "Classes" and "Interfaces" that we
// want to reorganize.
if (
"items" in category &&
(!("label" in category) ||
(category.label !== "Readme" &&
category.label !== "Table of contents" &&
category.label !== "modules"))
) {
for (const item of category.items) {
if (!("id" in item)) {
continue;
}
// The original item ID looks like "api/classes/browser.ConvexHttpClient"
// and we want to extract "browser" because that's the entry point.
const pathParts = item.id.split("/");
const itemName = pathParts[pathParts.length - 1];
// Undo react-auth0 -> react_auth0 normalization.
const entryPoint = itemName.split(".")[0].replace("_", "-");
if (!ENTRY_POINTS_TO_DOCUMENT.includes(entryPoint)) {
throw new Error(
"Couldn't sort API reference doc by entry point: " +
item.id,
);
}
entryPointToItems[entryPoint].push({
...item,
label: itemName.split(".")[1],
});
}
}
}
const entryPointCategories = ENTRY_POINTS_TO_DOCUMENT.map(
(entryPoint) => {
// Normalize the same way original sidebar items are.
const entryPointForId = entryPoint.replace("-", "_");
const items = entryPointToItems[entryPoint];
const id = "api/modules/" + entryPointForId;
const label = "convex/" + entryPoint;
return items.length === 0
? { type: "doc", id, label }
: {
type: "category",
label,
link: { type: "doc", id },
items,
};
},
);
return entryPointCategories;
},
},
blog: {
showReadingTime: true,
},
theme: {
customCss: require.resolve("./src/css/custom.css"),
},
}),
],
],
plugins: [
[
"docusaurus-plugin-typedoc",
{
id: "api",
entryPoints: ENTRY_POINTS_TO_DOCUMENT.map(
(entryPoint) => "../convex/src/" + entryPoint + "/index.ts",
),
tsconfig: "../convex/tsconfig.json",
excludePrivate: true,
excludeInternal: true,
// Don't generate "defined in" text when generating docs because our
// source isn't public.
disableSources: false,
sourceLinkTemplate:
"https://github.com/get-convex/convex-js/blob/main/{path}#L{line}",
gitRemote: "https://github.com/get-convex/convex-js",
basePath: "../convex/src",
// Keep everything in source order so we can be intentional about our
// ordering. This seems to only work for functions, variables and type
// aliases but it's something.
sort: "source-order",
out: "api",
sidebar: {
// Don't generate sidebar_label so we can always define it ourselves
autoConfiguration: false,
},
},
],
"./src/plugins/metrics",
"./src/plugins/prefixIds",
async function tailwindPlugin() {
return {
name: "docusaurus-tailwindcss",
configurePostCss(postcssOptions) {
postcssOptions.plugins.push(require("tailwindcss"));
postcssOptions.plugins.push(require("autoprefixer"));
return postcssOptions;
},
};
},
],
scripts: [
{
src: "https://plausible.io/js/script.js",
defer: true,
"data-domain": "docs.convex.dev",
},
{
src: "https://widget.kapa.ai/kapa-widget.bundle.js",
"data-button-hide": "true",
"data-modal-override-open-class": "js-launch-kapa-ai",
"data-website-id": "a20c0988-f33e-452b-9174-5045a58b965d",
"data-project-name": "Convex",
"data-project-color": "#141414",
"data-project-logo":
"https://img.stackshare.io/service/41143/default_f1d33b63d360437ba28c8ac981dd68d7d2478b22.png",
"data-user-analytics-fingerprint-enabled": "true",
async: true,
},
],
};
module.exports = config;