├── .browserslistrc
├── .github
└── workflows
│ └── push.yml
├── .gitignore
├── CHANGELOG.md
├── README.md
├── bin
└── ignite.js
├── docs
├── css
│ └── syntax-highlighting-overrides.css
├── next-env.d.ts
├── pages
│ ├── _app.tsx
│ ├── _document.js
│ ├── blog.js
│ ├── blog
│ │ ├── first.mdx
│ │ └── second.mdx
│ ├── docs
│ │ ├── _sidebar.mdx
│ │ ├── advanced-features
│ │ │ ├── javascript-pages.mdx
│ │ │ ├── layouts.mdx
│ │ │ ├── next.mdx
│ │ │ ├── pwa.mdx
│ │ │ └── theming.mdx
│ │ ├── cli.mdx
│ │ ├── configuration.mdx
│ │ ├── features
│ │ │ ├── blog.mdx
│ │ │ ├── custom-sidebar.mdx
│ │ │ ├── home-page.mdx
│ │ │ ├── markdown-components.mdx
│ │ │ └── multi-docs.mdx
│ │ ├── getting-started.mdx
│ │ └── index.mdx
│ └── index.mdx
├── public
│ ├── images
│ │ ├── favicon-dark.png
│ │ └── favicon.ico
│ ├── logo.svg
│ └── manifest.json
└── tsconfig.json
├── next.d.ts
├── next.js
├── package.json
├── postcss.config.js
├── src
├── components
│ ├── avatar.tsx
│ ├── blog-index.tsx
│ ├── mdx-components.tsx
│ ├── navbar.tsx
│ ├── open-graph-tags.tsx
│ └── sidebar.tsx
├── css
│ └── tailwind.css
├── index.ts
├── layouts
│ ├── blog.tsx
│ ├── docs.tsx
│ ├── home-page.tsx
│ ├── nav-bar.tsx
│ └── none.tsx
├── next.ts
└── utils
│ ├── build-rss-feed.ts
│ ├── build-search-index.ts
│ ├── create-additional-manifest-asset.ts
│ ├── docs-data.ts
│ ├── format-path.ts
│ ├── generate-pwa-assets.ts
│ ├── get-author.ts
│ ├── get-blog-posts.ts
│ ├── get-config.ts
│ ├── get-env.ts
│ ├── get-front-matters.ts
│ ├── is-dark-mode.ts
│ ├── mdx-lang.json
│ ├── mobile-menu-context.ts
│ ├── purge-unused-css.ts
│ ├── sitemap.ts
│ └── types.ts
├── tailwind.config.js
├── template
├── pages
│ ├── __app.tsx
│ └── docs
│ │ └── index.mdx
└── public
│ └── favicon.ico
├── tsconfig.json
├── typings
└── next-prefixed.d.ts
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | defaults
2 | not IE 11
3 | maintained node versions
--------------------------------------------------------------------------------
/.github/workflows/push.yml:
--------------------------------------------------------------------------------
1 | name: Node CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 |
9 | if: "!contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'skip ci')"
10 |
11 | steps:
12 | - uses: actions/checkout@v2
13 |
14 | - name: Prepare repository
15 | run: git fetch --unshallow --tags
16 |
17 | - name: Use Node.js ${{ matrix.node-version }}
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: ${{ matrix.node-version }}
21 |
22 | - name: npm install, build, release
23 | env:
24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
26 | run: |
27 | yarn install --frozen-lockfile
28 | yarn build:lib
29 | yarn release
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | search.json
4 | dist
5 |
6 | # dependencies
7 | /node_modules
8 | /.pnp
9 | .pnp.js
10 |
11 | # testing
12 | /coverage
13 |
14 | # next.js
15 | /.next/
16 | /out/
17 |
18 | # production
19 | /build
20 |
21 | # misc
22 | .DS_Store
23 | .env*
24 |
25 | # debug
26 | npm-debug.log*
27 | yarn-debug.log*
28 | yarn-error.log*
29 |
30 | # Ignore next-mdx-enhanced cache directory
31 | docs/.mdx-data
32 | docs/.next
33 | docs/out
34 | docs/public/search-index.json
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # v0.10.11 (Mon Mar 22 2021)
2 |
3 | #### ⚠️ Pushed to `master`
4 |
5 | - fix syntax error ([@hipstersmoothie](https://github.com/hipstersmoothie))
6 |
7 | #### Authors: 1
8 |
9 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
10 |
11 | ---
12 |
13 | # v0.10.10 (Mon Mar 22 2021)
14 |
15 | #### ⚠️ Pushed to `master`
16 |
17 | - fix getting ignite options from next.config.js for static build steps ([@hipstersmoothie](https://github.com/hipstersmoothie))
18 |
19 | #### Authors: 1
20 |
21 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
22 |
23 | ---
24 |
25 | # v0.10.9 (Fri Mar 19 2021)
26 |
27 | #### ⚠️ Pushed to `master`
28 |
29 | - add "none" layout ([@hipstersmoothie](https://github.com/hipstersmoothie))
30 |
31 | #### Authors: 1
32 |
33 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
34 |
35 | ---
36 |
37 | # v0.10.8 (Fri Mar 19 2021)
38 |
39 | #### ⚠️ Pushed to `master`
40 |
41 | - use published rehpye shiki plugin ([@hipstersmoothie](https://github.com/hipstersmoothie))
42 |
43 | #### Authors: 1
44 |
45 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
46 |
47 | ---
48 |
49 | # v0.10.7 (Sat Feb 20 2021)
50 |
51 | #### ⚠️ Pushed to `master`
52 |
53 | - only create shiki highlighter/theme once ([@hipstersmoothie](https://github.com/hipstersmoothie))
54 |
55 | #### Authors: 1
56 |
57 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
58 |
59 | ---
60 |
61 | # v0.10.6 (Sat Feb 20 2021)
62 |
63 | #### ⚠️ Pushed to `master`
64 |
65 | - target modern JS ([@hipstersmoothie](https://github.com/hipstersmoothie))
66 |
67 | #### Authors: 1
68 |
69 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
70 |
71 | ---
72 |
73 | # v0.10.5 (Fri Feb 19 2021)
74 |
75 | #### ⚠️ Pushed to `master`
76 |
77 | - fix overflowing code block ([@hipstersmoothie](https://github.com/hipstersmoothie))
78 |
79 | #### Authors: 1
80 |
81 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
82 |
83 | ---
84 |
85 | # v0.10.4 (Fri Feb 19 2021)
86 |
87 | #### ⚠️ Pushed to `master`
88 |
89 | - don't format direct links to headings ([@hipstersmoothie](https://github.com/hipstersmoothie))
90 |
91 | #### Authors: 1
92 |
93 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
94 |
95 | ---
96 |
97 | # v0.10.3 (Sun Feb 14 2021)
98 |
99 | #### ⚠️ Pushed to `master`
100 |
101 | - only render domain if url is configured ([@hipstersmoothie](https://github.com/hipstersmoothie))
102 |
103 | #### Authors: 1
104 |
105 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
106 |
107 | ---
108 |
109 | # v0.10.2 (Sun Feb 14 2021)
110 |
111 | #### ⚠️ Pushed to `master`
112 |
113 | - further fix graph url problem ([@hipstersmoothie](https://github.com/hipstersmoothie))
114 |
115 | #### Authors: 1
116 |
117 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
118 |
119 | ---
120 |
121 | # v0.10.1 (Sun Feb 14 2021)
122 |
123 | #### ⚠️ Pushed to `master`
124 |
125 | - fix typescript template ([@hipstersmoothie](https://github.com/hipstersmoothie))
126 | - fix unconfigured graph tag render ([@hipstersmoothie](https://github.com/hipstersmoothie))
127 | - fix clean init ([@hipstersmoothie](https://github.com/hipstersmoothie))
128 |
129 | #### Authors: 1
130 |
131 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
132 |
133 | ---
134 |
135 | # v0.10.0 (Sun Feb 14 2021)
136 |
137 | ### Release Notes
138 |
139 | #### move to shiki for syntax highlighting ([#38](https://github.com/hipstersmoothie/next-ignite/pull/38))
140 |
141 | If you are upgrading to this release you must remove all references to `prism` from your website and optionally configure a dark and light syntax theme through your `next-ignite` configuration.
142 |
143 | ---
144 |
145 | #### 🚀 Enhancement
146 |
147 | - move to shiki for syntax highlighting [#38](https://github.com/hipstersmoothie/next-ignite/pull/38) ([@hipstersmoothie](https://github.com/hipstersmoothie))
148 |
149 | #### Authors: 1
150 |
151 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
152 |
153 | ---
154 |
155 | # v0.9.21 (Sun Feb 14 2021)
156 |
157 | #### ⚠️ Pushed to `master`
158 |
159 | - add meta tags in layouts ([@hipstersmoothie](https://github.com/hipstersmoothie))
160 |
161 | #### Authors: 1
162 |
163 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
164 |
165 | ---
166 |
167 | # v0.9.20 (Thu Feb 11 2021)
168 |
169 | #### ⚠️ Pushed to `master`
170 |
171 | - include types in npm package ([@hipstersmoothie](https://github.com/hipstersmoothie))
172 |
173 | #### Authors: 1
174 |
175 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
176 |
177 | ---
178 |
179 | # v0.9.19 (Thu Feb 11 2021)
180 |
181 | #### ⚠️ Pushed to `master`
182 |
183 | - working ([@hipstersmoothie](https://github.com/hipstersmoothie))
184 |
185 | #### Authors: 1
186 |
187 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
188 |
189 | ---
190 |
191 | # v0.9.18 (Thu Feb 11 2021)
192 |
193 | #### ⚠️ Pushed to `master`
194 |
195 | - actually use plugins ([@hipstersmoothie](https://github.com/hipstersmoothie))
196 |
197 | #### Authors: 1
198 |
199 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
200 |
201 | ---
202 |
203 | # v0.9.17 (Thu Feb 11 2021)
204 |
205 | #### ⚠️ Pushed to `master`
206 |
207 | - add support for custom remark and rehype plugins ([@hipstersmoothie](https://github.com/hipstersmoothie))
208 |
209 | #### Authors: 1
210 |
211 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
212 |
213 | ---
214 |
215 | # v0.9.16 (Thu Jan 28 2021)
216 |
217 | #### ⚠️ Pushed to `master`
218 |
219 | - replace double quotes in meta description ([@hipstersmoothie](https://github.com/hipstersmoothie))
220 |
221 | #### Authors: 1
222 |
223 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
224 |
225 | ---
226 |
227 | # v0.9.15 (Thu Jan 28 2021)
228 |
229 | #### ⚠️ Pushed to `master`
230 |
231 | - fix search input keyboard ([@hipstersmoothie](https://github.com/hipstersmoothie))
232 |
233 | #### Authors: 1
234 |
235 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
236 |
237 | ---
238 |
239 | # v0.9.14 (Wed Jan 27 2021)
240 |
241 | #### ⚠️ Pushed to `master`
242 |
243 | - fix keyboard search nav ([@hipstersmoothie](https://github.com/hipstersmoothie))
244 |
245 | #### Authors: 1
246 |
247 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
248 |
249 | ---
250 |
251 | # v0.9.13 (Wed Jan 27 2021)
252 |
253 | #### ⚠️ Pushed to `master`
254 |
255 | - inject html manifest assets at end of build ([@hipstersmoothie](https://github.com/hipstersmoothie))
256 | - fix public asset paths ([@hipstersmoothie](https://github.com/hipstersmoothie))
257 |
258 | #### Authors: 1
259 |
260 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
261 |
262 | ---
263 |
264 | # v0.9.12 (Wed Jan 27 2021)
265 |
266 | #### ⚠️ Pushed to `master`
267 |
268 | - set unique title and description for each page ([@hipstersmoothie](https://github.com/hipstersmoothie))
269 |
270 | #### Authors: 1
271 |
272 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
273 |
274 | ---
275 |
276 | # v0.9.11 (Wed Jan 27 2021)
277 |
278 | #### ⚠️ Pushed to `master`
279 |
280 | - precache all HTML files for PWA ([@hipstersmoothie](https://github.com/hipstersmoothie))
281 |
282 | #### Authors: 1
283 |
284 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
285 |
286 | ---
287 |
288 | # v0.9.10 (Wed Jan 27 2021)
289 |
290 | #### ⚠️ Pushed to `master`
291 |
292 | - fix theme color ([@hipstersmoothie](https://github.com/hipstersmoothie))
293 |
294 | #### Authors: 1
295 |
296 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
297 |
298 | ---
299 |
300 | # v0.9.9 (Wed Jan 27 2021)
301 |
302 | #### ⚠️ Pushed to `master`
303 |
304 | - generate dark assets with dark logo ([@hipstersmoothie](https://github.com/hipstersmoothie))
305 |
306 | #### Authors: 1
307 |
308 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
309 |
310 | ---
311 |
312 | # v0.9.8 (Wed Jan 27 2021)
313 |
314 | #### ⚠️ Pushed to `master`
315 |
316 | - add description ([@hipstersmoothie](https://github.com/hipstersmoothie))
317 |
318 | #### Authors: 1
319 |
320 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
321 |
322 | ---
323 |
324 | # v0.9.7 (Tue Jan 26 2021)
325 |
326 | #### ⚠️ Pushed to `master`
327 |
328 | - add to sidebar ([@hipstersmoothie](https://github.com/hipstersmoothie))
329 |
330 | #### Authors: 1
331 |
332 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
333 |
334 | ---
335 |
336 | # v0.9.6 (Tue Jan 26 2021)
337 |
338 | #### ⚠️ Pushed to `master`
339 |
340 | - generate dark mode PWA assets ([@hipstersmoothie](https://github.com/hipstersmoothie))
341 | - use html ([@hipstersmoothie](https://github.com/hipstersmoothie))
342 | - add manifest back to head ([@hipstersmoothie](https://github.com/hipstersmoothie))
343 |
344 | #### Authors: 1
345 |
346 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
347 |
348 | ---
349 |
350 | # v0.9.5 (Tue Jan 26 2021)
351 |
352 | #### ⚠️ Pushed to `master`
353 |
354 | - use manifest description instead ([@hipstersmoothie](https://github.com/hipstersmoothie))
355 | - simplify pwa setup ([@hipstersmoothie](https://github.com/hipstersmoothie))
356 |
357 | #### Authors: 1
358 |
359 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
360 |
361 | ---
362 |
363 | # v0.9.4 (Tue Jan 26 2021)
364 |
365 | #### ⚠️ Pushed to `master`
366 |
367 | - use app bg color for app icon ([@hipstersmoothie](https://github.com/hipstersmoothie))
368 |
369 | #### Authors: 1
370 |
371 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
372 |
373 | ---
374 |
375 | # v0.9.3 (Tue Jan 26 2021)
376 |
377 | #### ⚠️ Pushed to `master`
378 |
379 | - fix start-url ([@hipstersmoothie](https://github.com/hipstersmoothie))
380 | - reduce title scroll top ([@hipstersmoothie](https://github.com/hipstersmoothie))
381 | - remove page scroll position weirdness ([@hipstersmoothie](https://github.com/hipstersmoothie))
382 |
383 | #### Authors: 1
384 |
385 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
386 |
387 | ---
388 |
389 | # v0.9.2 (Mon Jan 25 2021)
390 |
391 | #### ⚠️ Pushed to `master`
392 |
393 | - pass hrefs to anchors ([@hipstersmoothie](https://github.com/hipstersmoothie))
394 | - fallback to default logo if dark doesn't exist ([@hipstersmoothie](https://github.com/hipstersmoothie))
395 | - use next link for search result ([@hipstersmoothie](https://github.com/hipstersmoothie))
396 | - automate start_url ([@hipstersmoothie](https://github.com/hipstersmoothie))
397 | - fix base cache? ([@hipstersmoothie](https://github.com/hipstersmoothie))
398 |
399 | #### Authors: 1
400 |
401 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
402 |
403 | ---
404 |
405 | # v0.9.1 (Mon Jan 25 2021)
406 |
407 | #### ⚠️ Pushed to `master`
408 |
409 | - fix overscroll dark background ([@hipstersmoothie](https://github.com/hipstersmoothie))
410 |
411 | #### Authors: 1
412 |
413 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
414 |
415 | ---
416 |
417 | # v0.9.0 (Mon Jan 25 2021)
418 |
419 | #### 🚀 Enhancement
420 |
421 | - Make PWA if manifest.json is available [#36](https://github.com/hipstersmoothie/next-ignite/pull/36) ([@hipstersmoothie](https://github.com/hipstersmoothie))
422 |
423 | #### ⚠️ Pushed to `master`
424 |
425 | - improve search on mobile ([@hipstersmoothie](https://github.com/hipstersmoothie))
426 |
427 | #### Authors: 1
428 |
429 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
430 |
431 | ---
432 |
433 | # v0.8.23 (Fri Jan 22 2021)
434 |
435 | #### ⚠️ Pushed to `master`
436 |
437 | - fix sidebar position saving ([@hipstersmoothie](https://github.com/hipstersmoothie))
438 |
439 | #### Authors: 1
440 |
441 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
442 |
443 | ---
444 |
445 | # v0.8.22 (Fri Jan 15 2021)
446 |
447 | #### ⚠️ Pushed to `master`
448 |
449 | - fix overflowing doc page content ([@hipstersmoothie](https://github.com/hipstersmoothie))
450 |
451 | #### Authors: 1
452 |
453 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
454 |
455 | ---
456 |
457 | # v0.8.21 (Thu Jan 14 2021)
458 |
459 | #### ⚠️ Pushed to `master`
460 |
461 | - fix search index build ([@hipstersmoothie](https://github.com/hipstersmoothie))
462 |
463 | #### Authors: 1
464 |
465 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
466 |
467 | ---
468 |
469 | # v0.8.19 (Wed Jan 13 2021)
470 |
471 | #### ⚠️ Pushed to `master`
472 |
473 | - bigger margin on blog index ([@hipstersmoothie](https://github.com/hipstersmoothie))
474 |
475 | #### Authors: 1
476 |
477 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
478 |
479 | ---
480 |
481 | # v0.8.18 (Wed Jan 13 2021)
482 |
483 | #### ⚠️ Pushed to `master`
484 |
485 | - fix big card avatar size ([@hipstersmoothie](https://github.com/hipstersmoothie))
486 |
487 | #### Authors: 1
488 |
489 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
490 |
491 | ---
492 |
493 | # v0.8.17 (Wed Jan 13 2021)
494 |
495 | #### ⚠️ Pushed to `master`
496 |
497 | - return if no comment area ([@hipstersmoothie](https://github.com/hipstersmoothie))
498 | - fix markup ([@hipstersmoothie](https://github.com/hipstersmoothie))
499 |
500 | #### Authors: 1
501 |
502 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
503 |
504 | ---
505 |
506 | # v0.8.16 (Wed Jan 13 2021)
507 |
508 | #### ⚠️ Pushed to `master`
509 |
510 | - isomorphic getFrontMatters ([@hipstersmoothie](https://github.com/hipstersmoothie))
511 | - add disqus docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
512 | - layout better with few posts ([@hipstersmoothie](https://github.com/hipstersmoothie))
513 | - fix avatar load jump ([@hipstersmoothie](https://github.com/hipstersmoothie))
514 | - shadows in light mode ([@hipstersmoothie](https://github.com/hipstersmoothie))
515 | - remove randomization ([@hipstersmoothie](https://github.com/hipstersmoothie))
516 | - light mode for blog ([@hipstersmoothie](https://github.com/hipstersmoothie))
517 | - improved blog index ([@hipstersmoothie](https://github.com/hipstersmoothie))
518 | - blog descriptions ([@hipstersmoothie](https://github.com/hipstersmoothie))
519 |
520 | #### Authors: 1
521 |
522 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
523 |
524 | ---
525 |
526 | # v0.8.15 (Wed Jan 13 2021)
527 |
528 | #### ⚠️ Pushed to `master`
529 |
530 | - fix build ([@hipstersmoothie](https://github.com/hipstersmoothie))
531 | - fix search index sectioning ([@hipstersmoothie](https://github.com/hipstersmoothie))
532 | - design updates ([@hipstersmoothie](https://github.com/hipstersmoothie))
533 |
534 | #### Authors: 1
535 |
536 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
537 |
538 | ---
539 |
540 | # v0.8.14 (Tue Jan 12 2021)
541 |
542 | #### 🐛 Bug Fix
543 |
544 | - purge after next build so any 3rd party components are taken into account [#33](https://github.com/hipstersmoothie/next-ignite/pull/33) ([@hipstersmoothie](https://github.com/hipstersmoothie))
545 |
546 | #### Authors: 1
547 |
548 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
549 |
550 | ---
551 |
552 | # v0.8.13 (Tue Jan 12 2021)
553 |
554 | #### ⚠️ Pushed to `master`
555 |
556 | - fix building docs for root ([@hipstersmoothie](https://github.com/hipstersmoothie))
557 | - fix search-index build w/inconsistent headings, no lvls ([@hipstersmoothie](https://github.com/hipstersmoothie))
558 |
559 | #### Authors: 1
560 |
561 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
562 |
563 | ---
564 |
565 | # v0.8.12 (Tue Jan 12 2021)
566 |
567 | #### ⚠️ Pushed to `master`
568 |
569 | - fix logo link href ([@hipstersmoothie](https://github.com/hipstersmoothie))
570 |
571 | #### Authors: 1
572 |
573 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
574 |
575 | ---
576 |
577 | # v0.8.11 (Tue Jan 12 2021)
578 |
579 | #### ⚠️ Pushed to `master`
580 |
581 | - fix search result links ([@hipstersmoothie](https://github.com/hipstersmoothie))
582 | - fix logo link when using html URLs ([@hipstersmoothie](https://github.com/hipstersmoothie))
583 | - only purge-css in production ([@hipstersmoothie](https://github.com/hipstersmoothie))
584 |
585 | #### Authors: 1
586 |
587 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
588 |
589 | ---
590 |
591 | # v0.8.10 (Mon Jan 11 2021)
592 |
593 | #### ⚠️ Pushed to `master`
594 |
595 | - improve home page mobile ([@hipstersmoothie](https://github.com/hipstersmoothie))
596 | - fix sidebar mobile rendering and small items ([@hipstersmoothie](https://github.com/hipstersmoothie))
597 |
598 | #### Authors: 1
599 |
600 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
601 |
602 | ---
603 |
604 | # v0.8.9 (Mon Jan 11 2021)
605 |
606 | #### ⚠️ Pushed to `master`
607 |
608 | - group search results by lvl0 heading ([@hipstersmoothie](https://github.com/hipstersmoothie))
609 |
610 | #### Authors: 1
611 |
612 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
613 |
614 | ---
615 |
616 | # v0.8.8 (Mon Jan 11 2021)
617 |
618 | #### ⚠️ Pushed to `master`
619 |
620 | - debounce + optimize search input ([@hipstersmoothie](https://github.com/hipstersmoothie))
621 |
622 | #### Authors: 1
623 |
624 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
625 |
626 | ---
627 |
628 | # v0.8.7 (Mon Jan 11 2021)
629 |
630 | #### ⚠️ Pushed to `master`
631 |
632 | - remove unnecessary dark mode logic ([@hipstersmoothie](https://github.com/hipstersmoothie))
633 |
634 | #### Authors: 1
635 |
636 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
637 |
638 | ---
639 |
640 | # v0.8.6 (Mon Jan 11 2021)
641 |
642 | #### ⚠️ Pushed to `master`
643 |
644 | - fix color inclusing ([@hipstersmoothie](https://github.com/hipstersmoothie))
645 |
646 | #### Authors: 1
647 |
648 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
649 |
650 | ---
651 |
652 | # v0.8.5 (Mon Jan 11 2021)
653 |
654 | #### ⚠️ Pushed to `master`
655 |
656 | - include skip-nav css ([@hipstersmoothie](https://github.com/hipstersmoothie))
657 |
658 | #### Authors: 1
659 |
660 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
661 |
662 | ---
663 |
664 | # v0.8.4 (Mon Jan 11 2021)
665 |
666 | #### ⚠️ Pushed to `master`
667 |
668 | - closes results when user clicks an item ([@hipstersmoothie](https://github.com/hipstersmoothie))
669 |
670 | #### Authors: 1
671 |
672 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
673 |
674 | ---
675 |
676 | # v0.8.3 (Mon Jan 11 2021)
677 |
678 | #### ⚠️ Pushed to `master`
679 |
680 | - turn off autocomplete on search input ([@hipstersmoothie](https://github.com/hipstersmoothie))
681 |
682 | #### Authors: 1
683 |
684 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
685 |
686 | ---
687 |
688 | # v0.8.2 (Mon Jan 11 2021)
689 |
690 | #### ⚠️ Pushed to `master`
691 |
692 | - add tailwind extractor for purgecss ([@hipstersmoothie](https://github.com/hipstersmoothie))
693 | - fix deployed search-index.json ([@hipstersmoothie](https://github.com/hipstersmoothie))
694 |
695 | #### Authors: 1
696 |
697 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
698 |
699 | ---
700 |
701 | # v0.8.1 (Mon Jan 11 2021)
702 |
703 | #### ⚠️ Pushed to `master`
704 |
705 | - fix `dev` command ([@hipstersmoothie](https://github.com/hipstersmoothie))
706 |
707 | #### Authors: 1
708 |
709 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
710 |
711 | ---
712 |
713 | # v0.8.0 (Mon Jan 11 2021)
714 |
715 | ### Release Notes
716 |
717 | _From #32_
718 |
719 | This release has a bunch of new features and a refreshed design.
720 |
721 | **New Features:**
722 |
723 | - Purge unused CSS
724 | - RSS feed for blog
725 | - Built-in search
726 |
727 | **Dependency Updates:**
728 |
729 | - Tailwind 2.0
730 | - Next 10.0
731 |
732 | ---
733 |
734 | #### 🚀 Enhancement
735 |
736 | - Design + Tech ReFresh [#32](https://github.com/hipstersmoothie/next-ignite/pull/32) ([@hipstersmoothie](https://github.com/hipstersmoothie))
737 |
738 | #### Authors: 1
739 |
740 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
741 |
742 | ---
743 |
744 | # v0.7.14 (Sun Jan 10 2021)
745 |
746 | #### ⚠️ Pushed to `master`
747 |
748 | - add skip-nav button ([@hipstersmoothie](https://github.com/hipstersmoothie))
749 |
750 | #### Authors: 1
751 |
752 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
753 |
754 | ---
755 |
756 | # v0.7.13 (Sun Jan 10 2021)
757 |
758 | #### ⚠️ Pushed to `master`
759 |
760 | - upgrade tailwind and improve focus styling ([@hipstersmoothie](https://github.com/hipstersmoothie))
761 |
762 | #### Authors: 1
763 |
764 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
765 |
766 | ---
767 |
768 | # v0.7.12 (Fri Jan 08 2021)
769 |
770 | #### ⚠️ Pushed to `master`
771 |
772 | - show correct dev URL ([@hipstersmoothie](https://github.com/hipstersmoothie))
773 |
774 | #### Authors: 1
775 |
776 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
777 |
778 | ---
779 |
780 | # v0.7.11 (Fri Jan 08 2021)
781 |
782 | #### ⚠️ Pushed to `master`
783 |
784 | - only render front matter title if it exists ([@hipstersmoothie](https://github.com/hipstersmoothie))
785 |
786 | #### Authors: 1
787 |
788 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
789 |
790 | ---
791 |
792 | # v0.7.10 (Fri Jan 08 2021)
793 |
794 | #### ⚠️ Pushed to `master`
795 |
796 | - stringify and parse json structure to fix server/client rendering ([@hipstersmoothie](https://github.com/hipstersmoothie))
797 |
798 | #### Authors: 1
799 |
800 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
801 |
802 | ---
803 |
804 | # v0.7.9 (Fri Jan 08 2021)
805 |
806 | #### ⚠️ Pushed to `master`
807 |
808 | - use nextConfig.env + process.env to expose varaiable + main now works ([@hipstersmoothie](https://github.com/hipstersmoothie))
809 |
810 | #### Authors: 1
811 |
812 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
813 |
814 | ---
815 |
816 | # v0.7.8 (Fri Jan 08 2021)
817 |
818 | #### ⚠️ Pushed to `master`
819 |
820 | - correct import name to next-ignite ([@hipstersmoothie](https://github.com/hipstersmoothie))
821 |
822 | #### Authors: 1
823 |
824 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
825 |
826 | ---
827 |
828 | # v0.7.7 (Thu Jan 07 2021)
829 |
830 | #### ⚠️ Pushed to `master`
831 |
832 | - add main for cjs ([@hipstersmoothie](https://github.com/hipstersmoothie))
833 |
834 | #### Authors: 1
835 |
836 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
837 |
838 | ---
839 |
840 | # v0.7.6 (Thu Jan 07 2021)
841 |
842 | #### ⚠️ Pushed to `master`
843 |
844 | - expose docs url ([@hipstersmoothie](https://github.com/hipstersmoothie))
845 |
846 | #### Authors: 1
847 |
848 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
849 |
850 | ---
851 |
852 | # v0.7.5 (Thu Jan 07 2021)
853 |
854 | #### ⚠️ Pushed to `master`
855 |
856 | - forward refs to search input ([@hipstersmoothie](https://github.com/hipstersmoothie))
857 |
858 | #### Authors: 1
859 |
860 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
861 |
862 | ---
863 |
864 | # v0.7.4 (Wed Nov 25 2020)
865 |
866 | #### ⚠️ Pushed to `master`
867 |
868 | - remove mdx from blog post paths ([@hipstersmoothie](https://github.com/hipstersmoothie))
869 |
870 | #### Authors: 1
871 |
872 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
873 |
874 | ---
875 |
876 | # v0.7.3 (Wed Nov 25 2020)
877 |
878 | #### ⚠️ Pushed to `master`
879 |
880 | - refactor unnamed default exports ([@hipstersmoothie](https://github.com/hipstersmoothie))
881 |
882 | #### Authors: 1
883 |
884 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
885 |
886 | ---
887 |
888 | # v0.7.2 (Wed Nov 25 2020)
889 |
890 | #### ⚠️ Pushed to `master`
891 |
892 | - fix blog post index links ([@hipstersmoothie](https://github.com/hipstersmoothie))
893 |
894 | #### 🔩 Dependency Updates
895 |
896 | - fix build issue [#28](https://github.com/hipstersmoothie/next-ignite/pull/28) ([@hipstersmoothie](https://github.com/hipstersmoothie))
897 |
898 | #### Authors: 1
899 |
900 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
901 |
902 | ---
903 |
904 | # v0.7.1 (Thu Oct 08 2020)
905 |
906 | #### 🐛 Bug Fix
907 |
908 | - set NODE_ENV before loading next.config.js [#26](https://github.com/hipstersmoothie/next-ignite/pull/26) ([@hipstersmoothie](https://github.com/hipstersmoothie))
909 |
910 | #### Authors: 1
911 |
912 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
913 |
914 | ---
915 |
916 | # v0.7.0 (Thu Oct 08 2020)
917 |
918 | #### 🚀 Enhancement
919 |
920 | - apply next.config.js if it's found [#25](https://github.com/hipstersmoothie/next-ignite/pull/25) ([@hipstersmoothie](https://github.com/hipstersmoothie))
921 |
922 | #### Authors: 1
923 |
924 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
925 |
926 | ---
927 |
928 | # v0.6.7 (Mon Sep 21 2020)
929 |
930 | #### ⚠️ Pushed to `master`
931 |
932 | - upgrade next version ([@hipstersmoothie](https://github.com/hipstersmoothie))
933 | - :pray: ([@hipstersmoothie](https://github.com/hipstersmoothie))
934 |
935 | #### Authors: 1
936 |
937 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
938 |
939 | ---
940 |
941 | # v0.6.6 (Tue Sep 01 2020)
942 |
943 | #### ⚠️ Pushed to `master`
944 |
945 | - fix home page url ([@hipstersmoothie](https://github.com/hipstersmoothie))
946 |
947 | #### Authors: 1
948 |
949 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
950 |
951 | ---
952 |
953 | # v0.6.5 (Tue Sep 01 2020)
954 |
955 | #### ⚠️ Pushed to `master`
956 |
957 | - add feature to add .html to end of urls ([@hipstersmoothie](https://github.com/hipstersmoothie))
958 | - fix linking to other mdx documents ([@hipstersmoothie](https://github.com/hipstersmoothie))
959 |
960 | #### Authors: 1
961 |
962 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
963 |
964 | ---
965 |
966 | # v0.6.4 (Tue Sep 01 2020)
967 |
968 | #### ⚠️ Pushed to `master`
969 |
970 | - fix sidebar links ([@hipstersmoothie](https://github.com/hipstersmoothie))
971 |
972 | #### Authors: 1
973 |
974 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
975 |
976 | ---
977 |
978 | # v0.6.3 (Tue Sep 01 2020)
979 |
980 | #### ⚠️ Pushed to `master`
981 |
982 | - clean up some formatPaths - not needed with new next.js ([@hipstersmoothie](https://github.com/hipstersmoothie))
983 |
984 | #### Authors: 1
985 |
986 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
987 |
988 | ---
989 |
990 | # v0.6.2 (Tue Sep 01 2020)
991 |
992 | #### 🐛 Bug Fix
993 |
994 | - base path no longer experimental [#22](https://github.com/hipstersmoothie/next-ignite/pull/22) ([@hipstersmoothie](https://github.com/hipstersmoothie))
995 |
996 | #### Authors: 1
997 |
998 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
999 |
1000 | ---
1001 |
1002 | # v0.6.1 (Tue Sep 01 2020)
1003 |
1004 | #### 🐛 Bug Fix
1005 |
1006 | - Url [#21](https://github.com/hipstersmoothie/next-ignite/pull/21) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1007 |
1008 | #### Authors: 1
1009 |
1010 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1011 |
1012 | ---
1013 |
1014 | # v0.6.0 (Tue Sep 01 2020)
1015 |
1016 | #### 🚀 Enhancement
1017 |
1018 | - upgrade next-mdx-enhanced. fix it all [#20](https://github.com/hipstersmoothie/next-ignite/pull/20) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1019 |
1020 | #### 🐛 Bug Fix
1021 |
1022 | - Revert "add purgecss" [#18](https://github.com/hipstersmoothie/next-ignite/pull/18) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1023 |
1024 | #### Authors: 1
1025 |
1026 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1027 |
1028 | ---
1029 |
1030 | # v0.5.0 (Wed Aug 05 2020)
1031 |
1032 | #### 🚀 Enhancement
1033 |
1034 | - add purgecss [#17](https://github.com/hipstersmoothie/next-ignite/pull/17) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1035 |
1036 | #### Authors: 1
1037 |
1038 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1039 |
1040 | ---
1041 |
1042 | # v0.4.2 (Thu Jul 30 2020)
1043 |
1044 | #### 🐛 Bug Fix
1045 |
1046 | - add space between sidebar heading sections [#14](https://github.com/hipstersmoothie/next-ignite/pull/14) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1047 |
1048 | #### Authors: 1
1049 |
1050 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1051 |
1052 | ---
1053 |
1054 | # v0.4.1 (Wed Jul 08 2020)
1055 |
1056 | #### ⚠️ Pushed to `master`
1057 |
1058 | - add prettier ([@hipstersmoothie](https://github.com/hipstersmoothie))
1059 | - save page scroll position ([@hipstersmoothie](https://github.com/hipstersmoothie))
1060 |
1061 | #### Authors: 1
1062 |
1063 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1064 |
1065 | ---
1066 |
1067 | # v0.4.0 (Tue Jul 07 2020)
1068 |
1069 | #### 🚀 Enhancement
1070 |
1071 | - Styling changes for dark mode and other enhancements [#11](https://github.com/hipstersmoothie/next-ignite/pull/11) (kelly_harrop@intuit.com [@hipstersmoothie](https://github.com/hipstersmoothie))
1072 |
1073 | #### Authors: 2
1074 |
1075 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1076 | - Kelly Harrop ([@kharrop](https://github.com/kharrop))
1077 |
1078 | ---
1079 |
1080 | # v0.3.7 (Mon Jul 06 2020)
1081 |
1082 | #### ⚠️ Pushed to `master`
1083 |
1084 | - Update README.md ([@hipstersmoothie](https://github.com/hipstersmoothie))
1085 |
1086 | #### Authors: 1
1087 |
1088 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1089 |
1090 | ---
1091 |
1092 | # v0.3.6 (Mon Jul 06 2020)
1093 |
1094 | #### ⚠️ Pushed to `master`
1095 |
1096 | - add default logo ([@hipstersmoothie](https://github.com/hipstersmoothie))
1097 | - print correct dev url ([@hipstersmoothie](https://github.com/hipstersmoothie))
1098 | - handle uninitialized git repos ([@hipstersmoothie](https://github.com/hipstersmoothie))
1099 | - fix init template ([@hipstersmoothie](https://github.com/hipstersmoothie))
1100 | - handle if no repo set ([@hipstersmoothie](https://github.com/hipstersmoothie))
1101 |
1102 | #### Authors: 1
1103 |
1104 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1105 |
1106 | ---
1107 |
1108 | # v0.3.5 (Mon Jul 06 2020)
1109 |
1110 | #### ⚠️ Pushed to `master`
1111 |
1112 | - handle when no URL is set ([@hipstersmoothie](https://github.com/hipstersmoothie))
1113 |
1114 | #### Authors: 1
1115 |
1116 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1117 |
1118 | ---
1119 |
1120 | # v0.3.4 (Mon Jul 06 2020)
1121 |
1122 | #### ⚠️ Pushed to `master`
1123 |
1124 | - add template to package ([@hipstersmoothie](https://github.com/hipstersmoothie))
1125 |
1126 | #### Authors: 1
1127 |
1128 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1129 |
1130 | ---
1131 |
1132 | # v0.3.3 (Sat Jul 04 2020)
1133 |
1134 | #### 🐛 Bug Fix
1135 |
1136 | - fix prod BASE_PATH [#10](https://github.com/hipstersmoothie/next-ignite/pull/10) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1137 |
1138 | #### Authors: 1
1139 |
1140 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1141 |
1142 | ---
1143 |
1144 | # v0.3.2 (Sat Jul 04 2020)
1145 |
1146 | #### 🐛 Bug Fix
1147 |
1148 | - add blog post class [#9](https://github.com/hipstersmoothie/next-ignite/pull/9) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1149 |
1150 | #### Authors: 1
1151 |
1152 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1153 |
1154 | ---
1155 |
1156 | # v0.3.1 (Sat Jul 04 2020)
1157 |
1158 | #### 🐛 Bug Fix
1159 |
1160 | - add lvl0 for docsearch [#8](https://github.com/hipstersmoothie/next-ignite/pull/8) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1161 |
1162 | #### Authors: 1
1163 |
1164 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1165 |
1166 | ---
1167 |
1168 | # v0.3.0 (Sat Jul 04 2020)
1169 |
1170 | #### 🚀 Enhancement
1171 |
1172 | - sitemap + change basePath to url [#7](https://github.com/hipstersmoothie/next-ignite/pull/7) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1173 |
1174 | #### Authors: 1
1175 |
1176 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1177 |
1178 | ---
1179 |
1180 | # v0.2.17 (Fri Jul 03 2020)
1181 |
1182 | #### ⚠️ Pushed to `master`
1183 |
1184 | - fix navbar spacing for search input ([@hipstersmoothie](https://github.com/hipstersmoothie))
1185 |
1186 | #### Authors: 1
1187 |
1188 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1189 |
1190 | ---
1191 |
1192 | # v0.2.16 (Fri Jul 03 2020)
1193 |
1194 | #### ⚠️ Pushed to `master`
1195 |
1196 | - fix wide tables on mobile ([@hipstersmoothie](https://github.com/hipstersmoothie))
1197 | - only whitespace-nowrap when inlineCode is in table ([@hipstersmoothie](https://github.com/hipstersmoothie))
1198 |
1199 | #### Authors: 1
1200 |
1201 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1202 |
1203 | ---
1204 |
1205 | # v0.2.15 (Fri Jul 03 2020)
1206 |
1207 | #### ⚠️ Pushed to `master`
1208 |
1209 | - give top level header more bottom margin ([@hipstersmoothie](https://github.com/hipstersmoothie))
1210 | - make inlineCode match surrounding text ([@hipstersmoothie](https://github.com/hipstersmoothie))
1211 |
1212 | #### Authors: 1
1213 |
1214 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1215 |
1216 | ---
1217 |
1218 | # v0.2.14 (Tue Jun 30 2020)
1219 |
1220 | #### ⚠️ Pushed to `master`
1221 |
1222 | - remove debug info ([@hipstersmoothie](https://github.com/hipstersmoothie))
1223 | - working ([@hipstersmoothie](https://github.com/hipstersmoothie))
1224 | - Revert "waffling" ([@hipstersmoothie](https://github.com/hipstersmoothie))
1225 | - waffling ([@hipstersmoothie](https://github.com/hipstersmoothie))
1226 |
1227 | #### Authors: 1
1228 |
1229 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1230 |
1231 | ---
1232 |
1233 | # v0.2.13 (Tue Jun 30 2020)
1234 |
1235 | #### ⚠️ Pushed to `master`
1236 |
1237 | - add debug info ([@hipstersmoothie](https://github.com/hipstersmoothie))
1238 |
1239 | #### Authors: 1
1240 |
1241 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1242 |
1243 | ---
1244 |
1245 | # v0.2.12 (Tue Jun 30 2020)
1246 |
1247 | #### ⚠️ Pushed to `master`
1248 |
1249 | - really fix build titls ([@hipstersmoothie](https://github.com/hipstersmoothie))
1250 |
1251 | #### Authors: 1
1252 |
1253 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1254 |
1255 | ---
1256 |
1257 | # v0.2.11 (Tue Jun 30 2020)
1258 |
1259 | #### ⚠️ Pushed to `master`
1260 |
1261 | - add debug info ([@hipstersmoothie](https://github.com/hipstersmoothie))
1262 |
1263 | #### Authors: 1
1264 |
1265 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1266 |
1267 | ---
1268 |
1269 | # v0.2.10 (Tue Jun 30 2020)
1270 |
1271 | #### 🐛 Bug Fix
1272 |
1273 | - fix prod open in new tab [#6](https://github.com/hipstersmoothie/next-ignite/pull/6) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1274 |
1275 | #### Authors: 1
1276 |
1277 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1278 |
1279 | ---
1280 |
1281 | # v0.2.9 (Tue Jun 30 2020)
1282 |
1283 | #### 🐛 Bug Fix
1284 |
1285 | - fix open in new tab during build [#5](https://github.com/hipstersmoothie/next-ignite/pull/5) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1286 |
1287 | #### Authors: 1
1288 |
1289 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1290 |
1291 | ---
1292 |
1293 | # v0.2.8 (Tue Jun 30 2020)
1294 |
1295 | #### 🐛 Bug Fix
1296 |
1297 | - fix "open in new tab" active/title for sidebar item [#4](https://github.com/hipstersmoothie/next-ignite/pull/4) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1298 |
1299 | #### Authors: 1
1300 |
1301 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1302 |
1303 | ---
1304 |
1305 | # v0.2.7 (Tue Jun 30 2020)
1306 |
1307 | #### 🐛 Bug Fix
1308 |
1309 | - fix "open link in new tab" [#3](https://github.com/hipstersmoothie/next-ignite/pull/3) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1310 |
1311 | #### Authors: 1
1312 |
1313 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1314 |
1315 | ---
1316 |
1317 | # v0.2.6 (Thu Jun 25 2020)
1318 |
1319 | #### ⚠️ Pushed to `master`
1320 |
1321 | - manually switch favicon when dark mode switches ([@hipstersmoothie](https://github.com/hipstersmoothie))
1322 |
1323 | #### Authors: 1
1324 |
1325 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1326 |
1327 | ---
1328 |
1329 | # v0.2.5 (Thu Jun 25 2020)
1330 |
1331 | #### ⚠️ Pushed to `master`
1332 |
1333 | - add dark mode favicon support ([@hipstersmoothie](https://github.com/hipstersmoothie))
1334 |
1335 | #### Authors: 1
1336 |
1337 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1338 |
1339 | ---
1340 |
1341 | # v0.2.4 (Thu Jun 25 2020)
1342 |
1343 | #### ⚠️ Pushed to `master`
1344 |
1345 | - remove backtick escape in page title ([@hipstersmoothie](https://github.com/hipstersmoothie))
1346 |
1347 | #### Authors: 1
1348 |
1349 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1350 |
1351 | ---
1352 |
1353 | # v0.2.3 (Thu Jun 25 2020)
1354 |
1355 | #### ⚠️ Pushed to `master`
1356 |
1357 | - fallback to PROJECT_NAME in title for index pages ([@hipstersmoothie](https://github.com/hipstersmoothie))
1358 |
1359 | #### Authors: 1
1360 |
1361 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1362 |
1363 | ---
1364 |
1365 | # v0.2.2 (Thu Jun 25 2020)
1366 |
1367 | #### ⚠️ Pushed to `master`
1368 |
1369 | - load favicon/logo from the public dir ([@hipstersmoothie](https://github.com/hipstersmoothie))
1370 |
1371 | #### Authors: 1
1372 |
1373 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1374 |
1375 | ---
1376 |
1377 | # v0.2.1 (Thu Jun 25 2020)
1378 |
1379 | #### ⚠️ Pushed to `master`
1380 |
1381 | - use isomorphic layout effect ([@hipstersmoothie](https://github.com/hipstersmoothie))
1382 |
1383 | #### Authors: 1
1384 |
1385 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1386 |
1387 | ---
1388 |
1389 | # v0.2.0 (Thu Jun 25 2020)
1390 |
1391 | #### 🚀 Enhancement
1392 |
1393 | - Add page titles + favicon [#2](https://github.com/hipstersmoothie/next-ignite/pull/2) ([@hipstersmoothie](https://github.com/hipstersmoothie))
1394 |
1395 | #### Authors: 1
1396 |
1397 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1398 |
1399 | ---
1400 |
1401 | # v0.1.33 (Mon Jun 15 2020)
1402 |
1403 | #### ⚠️ Pushed to `master`
1404 |
1405 | - fix blog index background color ([@hipstersmoothie](https://github.com/hipstersmoothie))
1406 |
1407 | #### Authors: 1
1408 |
1409 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1410 |
1411 | ---
1412 |
1413 | # v0.1.32 (Mon Jun 15 2020)
1414 |
1415 | #### ⚠️ Pushed to `master`
1416 |
1417 | - fix blog posts ([@hipstersmoothie](https://github.com/hipstersmoothie))
1418 |
1419 | #### Authors: 1
1420 |
1421 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1422 |
1423 | ---
1424 |
1425 | # v0.1.31 (Mon Jun 15 2020)
1426 |
1427 | #### ⚠️ Pushed to `master`
1428 |
1429 | - fix nested sidebar list indent ([@hipstersmoothie](https://github.com/hipstersmoothie))
1430 | - fix active link matcher ([@hipstersmoothie](https://github.com/hipstersmoothie))
1431 |
1432 | #### Authors: 1
1433 |
1434 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1435 |
1436 | ---
1437 |
1438 | # v0.1.30 (Mon Jun 15 2020)
1439 |
1440 | #### ⚠️ Pushed to `master`
1441 |
1442 | - fix double build ([@hipstersmoothie](https://github.com/hipstersmoothie))
1443 |
1444 | #### Authors: 1
1445 |
1446 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1447 |
1448 | ---
1449 |
1450 | # v0.1.29 (Mon Jun 15 2020)
1451 |
1452 | #### ⚠️ Pushed to `master`
1453 |
1454 | - prefix image sources ([@hipstersmoothie](https://github.com/hipstersmoothie))
1455 |
1456 | #### Authors: 1
1457 |
1458 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1459 |
1460 | ---
1461 |
1462 | # v0.1.28 (Mon Jun 15 2020)
1463 |
1464 | #### ⚠️ Pushed to `master`
1465 |
1466 | - add debugging info ([@hipstersmoothie](https://github.com/hipstersmoothie))
1467 |
1468 | #### Authors: 1
1469 |
1470 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1471 |
1472 | ---
1473 |
1474 | # v0.1.27 (Mon Jun 15 2020)
1475 |
1476 | #### ⚠️ Pushed to `master`
1477 |
1478 | - darken search input ([@hipstersmoothie](https://github.com/hipstersmoothie))
1479 |
1480 | #### Authors: 1
1481 |
1482 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1483 |
1484 | ---
1485 |
1486 | # v0.1.25 (Mon Jun 15 2020)
1487 |
1488 | #### ⚠️ Pushed to `master`
1489 |
1490 | - innline code doesn't wrap ([@hipstersmoothie](https://github.com/hipstersmoothie))
1491 |
1492 | #### Authors: 1
1493 |
1494 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1495 |
1496 | ---
1497 |
1498 | # v0.1.24 (Mon Jun 15 2020)
1499 |
1500 | #### ⚠️ Pushed to `master`
1501 |
1502 | - Merge branch 'master' of https://github.com/hipstersmoothie/next-ignite ([@hipstersmoothie](https://github.com/hipstersmoothie))
1503 | - fix just code block titles ([@hipstersmoothie](https://github.com/hipstersmoothie))
1504 | - downgrade next ([@hipstersmoothie](https://github.com/hipstersmoothie))
1505 |
1506 | #### Authors: 1
1507 |
1508 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1509 |
1510 | ---
1511 |
1512 | # v0.1.23 (Mon Jun 15 2020)
1513 |
1514 | #### ⚠️ Pushed to `master`
1515 |
1516 | - add dark mode logo ([@hipstersmoothie](https://github.com/hipstersmoothie))
1517 | - update config ([@hipstersmoothie](https://github.com/hipstersmoothie))
1518 |
1519 | #### Authors: 1
1520 |
1521 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1522 |
1523 | ---
1524 |
1525 | # v0.1.22 (Mon Jun 15 2020)
1526 |
1527 | #### ⚠️ Pushed to `master`
1528 |
1529 | - update lock file ([@hipstersmoothie](https://github.com/hipstersmoothie))
1530 | - remove search for now ([@hipstersmoothie](https://github.com/hipstersmoothie))
1531 | - fix bundle size except for search ([@hipstersmoothie](https://github.com/hipstersmoothie))
1532 |
1533 | #### Authors: 1
1534 |
1535 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1536 |
1537 | ---
1538 |
1539 | # v0.1.21 (Mon Jun 15 2020)
1540 |
1541 | #### ⚠️ Pushed to `master`
1542 |
1543 | - don't process title if there isn't one ([@hipstersmoothie](https://github.com/hipstersmoothie))
1544 |
1545 | #### Authors: 1
1546 |
1547 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1548 |
1549 | ---
1550 |
1551 | # v0.1.20 (Mon Jun 15 2020)
1552 |
1553 | #### ⚠️ Pushed to `master`
1554 |
1555 | - un-escape backticks in title ([@hipstersmoothie](https://github.com/hipstersmoothie))
1556 |
1557 | #### Authors: 1
1558 |
1559 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1560 |
1561 | ---
1562 |
1563 | # v0.1.19 (Sun Jun 14 2020)
1564 |
1565 | #### ⚠️ Pushed to `master`
1566 |
1567 | - allow for inline code block in the title of a page ([@hipstersmoothie](https://github.com/hipstersmoothie))
1568 |
1569 | #### Authors: 1
1570 |
1571 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1572 |
1573 | ---
1574 |
1575 | # v0.1.18 (Sun Jun 14 2020)
1576 |
1577 | #### ⚠️ Pushed to `master`
1578 |
1579 | - remove log ([@hipstersmoothie](https://github.com/hipstersmoothie))
1580 |
1581 | #### Authors: 1
1582 |
1583 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1584 |
1585 | ---
1586 |
1587 | # v0.1.17 (Sun Jun 14 2020)
1588 |
1589 | #### ⚠️ Pushed to `master`
1590 |
1591 | - fix search ([@hipstersmoothie](https://github.com/hipstersmoothie))
1592 |
1593 | #### Authors: 1
1594 |
1595 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1596 |
1597 | ---
1598 |
1599 | # v0.1.16 (Sun Jun 14 2020)
1600 |
1601 | #### ⚠️ Pushed to `master`
1602 |
1603 | - fix search bar placeholder theming ([@hipstersmoothie](https://github.com/hipstersmoothie))
1604 |
1605 | #### Authors: 1
1606 |
1607 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1608 |
1609 | ---
1610 |
1611 | # v0.1.15 (Sun Jun 14 2020)
1612 |
1613 | #### ⚠️ Pushed to `master`
1614 |
1615 | - fix gray colors ([@hipstersmoothie](https://github.com/hipstersmoothie))
1616 |
1617 | #### Authors: 1
1618 |
1619 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1620 |
1621 | ---
1622 |
1623 | # v0.1.14 (Sun Jun 14 2020)
1624 |
1625 | #### ⚠️ Pushed to `master`
1626 |
1627 | - remove theme ([@hipstersmoothie](https://github.com/hipstersmoothie))
1628 |
1629 | #### Authors: 1
1630 |
1631 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1632 |
1633 | ---
1634 |
1635 | # v0.1.13 (Sun Jun 14 2020)
1636 |
1637 | #### ⚠️ Pushed to `master`
1638 |
1639 | - add primary and gray theming ([@hipstersmoothie](https://github.com/hipstersmoothie))
1640 |
1641 | #### Authors: 1
1642 |
1643 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1644 |
1645 | ---
1646 |
1647 | # v0.1.12 (Wed Jun 10 2020)
1648 |
1649 | #### ⚠️ Pushed to `master`
1650 |
1651 | - better solution for retaining sidebar scroll position ([@hipstersmoothie](https://github.com/hipstersmoothie))
1652 |
1653 | #### Authors: 1
1654 |
1655 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1656 |
1657 | ---
1658 |
1659 | # v0.1.11 (Wed Jun 10 2020)
1660 |
1661 | #### ⚠️ Pushed to `master`
1662 |
1663 | - call scrollIntoViewIfNeeded ([@hipstersmoothie](https://github.com/hipstersmoothie))
1664 |
1665 | #### Authors: 1
1666 |
1667 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1668 |
1669 | ---
1670 |
1671 | # v0.1.10 (Wed Jun 10 2020)
1672 |
1673 | #### ⚠️ Pushed to `master`
1674 |
1675 | - upgrade next-mdx-enhanced ([@hipstersmoothie](https://github.com/hipstersmoothie))
1676 |
1677 | #### Authors: 1
1678 |
1679 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1680 |
1681 | ---
1682 |
1683 | # v0.1.9 (Wed Jun 10 2020)
1684 |
1685 | #### ⚠️ Pushed to `master`
1686 |
1687 | - fix image url ([@hipstersmoothie](https://github.com/hipstersmoothie))
1688 |
1689 | #### Authors: 1
1690 |
1691 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1692 |
1693 | ---
1694 |
1695 | # v0.1.8 (Wed Jun 10 2020)
1696 |
1697 | #### ⚠️ Pushed to `master`
1698 |
1699 | - fix blog header image width ([@hipstersmoothie](https://github.com/hipstersmoothie))
1700 |
1701 | #### Authors: 1
1702 |
1703 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1704 |
1705 | ---
1706 |
1707 | # v0.1.7 (Wed Jun 10 2020)
1708 |
1709 | #### ⚠️ Pushed to `master`
1710 |
1711 | - make sure sidebar link is in viewport ([@hipstersmoothie](https://github.com/hipstersmoothie))
1712 |
1713 | #### Authors: 1
1714 |
1715 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1716 |
1717 | ---
1718 |
1719 | # v0.1.6 (Wed Jun 10 2020)
1720 |
1721 | #### ⚠️ Pushed to `master`
1722 |
1723 | - detect logo ([@hipstersmoothie](https://github.com/hipstersmoothie))
1724 |
1725 | #### Authors: 1
1726 |
1727 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1728 |
1729 | ---
1730 |
1731 | # v0.1.5 (Tue Jun 09 2020)
1732 |
1733 | #### ⚠️ Pushed to `master`
1734 |
1735 | - fix import path ([@hipstersmoothie](https://github.com/hipstersmoothie))
1736 |
1737 | #### Authors: 1
1738 |
1739 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1740 |
1741 | ---
1742 |
1743 | # v0.1.4 (Tue Jun 09 2020)
1744 |
1745 | #### ⚠️ Pushed to `master`
1746 |
1747 | - fix layout path dir ([@hipstersmoothie](https://github.com/hipstersmoothie))
1748 |
1749 | #### Authors: 1
1750 |
1751 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1752 |
1753 | ---
1754 |
1755 | # v0.1.3 (Tue Jun 09 2020)
1756 |
1757 | #### ⚠️ Pushed to `master`
1758 |
1759 | - include dist files in package ([@hipstersmoothie](https://github.com/hipstersmoothie))
1760 |
1761 | #### Authors: 1
1762 |
1763 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1764 |
1765 | ---
1766 |
1767 | # v0.1.2 (Tue Jun 09 2020)
1768 |
1769 | #### ⚠️ Pushed to `master`
1770 |
1771 | - fix bin ([@hipstersmoothie](https://github.com/hipstersmoothie))
1772 |
1773 | #### Authors: 1
1774 |
1775 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1776 |
1777 | ---
1778 |
1779 | # v0.1.1 (Tue Jun 09 2020)
1780 |
1781 | #### ⚠️ Pushed to `master`
1782 |
1783 | - fix registry ([@hipstersmoothie](https://github.com/hipstersmoothie))
1784 | - fix build script ([@hipstersmoothie](https://github.com/hipstersmoothie))
1785 | - add actions ([@hipstersmoothie](https://github.com/hipstersmoothie))
1786 | - fix active link ([@hipstersmoothie](https://github.com/hipstersmoothie))
1787 | - some docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
1788 | - add dark mode ([@hipstersmoothie](https://github.com/hipstersmoothie))
1789 | - Press / to focus on search ([@hipstersmoothie](https://github.com/hipstersmoothie))
1790 | - document JS pages ([@hipstersmoothie](https://github.com/hipstersmoothie))
1791 | - order top level sections ([@hipstersmoothie](https://github.com/hipstersmoothie))
1792 | - make docs like any other section ([@hipstersmoothie](https://github.com/hipstersmoothie))
1793 | - fix: multiple search bars, double anchor for github link, ref forwarding for link components ([@hipstersmoothie](https://github.com/hipstersmoothie))
1794 | - fix build when no blog ([@hipstersmoothie](https://github.com/hipstersmoothie))
1795 | - add init command ([@hipstersmoothie](https://github.com/hipstersmoothie))
1796 | - GitHub link in navbar ([@hipstersmoothie](https://github.com/hipstersmoothie))
1797 | - headers become links ([@hipstersmoothie](https://github.com/hipstersmoothie))
1798 | - change hook name ([@hipstersmoothie](https://github.com/hipstersmoothie))
1799 | - fix token background in code examples ([@hipstersmoothie](https://github.com/hipstersmoothie))
1800 | - add the rest of the basic html elements ([@hipstersmoothie](https://github.com/hipstersmoothie))
1801 | - cleanup ([@hipstersmoothie](https://github.com/hipstersmoothie))
1802 | - add more todos ([@hipstersmoothie](https://github.com/hipstersmoothie))
1803 | - add cli docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
1804 | - fix export ([@hipstersmoothie](https://github.com/hipstersmoothie))
1805 | - add push-dir ([@hipstersmoothie](https://github.com/hipstersmoothie))
1806 | - actually get config ([@hipstersmoothie](https://github.com/hipstersmoothie))
1807 | - add docs for using as a next plugin ([@hipstersmoothie](https://github.com/hipstersmoothie))
1808 | - make configuration configurable ([@hipstersmoothie](https://github.com/hipstersmoothie))
1809 | - index links cannot end with / or /index ([@hipstersmoothie](https://github.com/hipstersmoothie))
1810 | - combine build and export ([@hipstersmoothie](https://github.com/hipstersmoothie))
1811 | - add deploy command ([@hipstersmoothie](https://github.com/hipstersmoothie))
1812 | - rename first page to index => no longer need 404 redirect :tada: ([@hipstersmoothie](https://github.com/hipstersmoothie))
1813 | - add multi-docs docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
1814 | - add basepath ([@hipstersmoothie](https://github.com/hipstersmoothie))
1815 | - add build and export ([@hipstersmoothie](https://github.com/hipstersmoothie))
1816 | - document blog features and automate blog author ([@hipstersmoothie](https://github.com/hipstersmoothie))
1817 | - add blog page layout ([@hipstersmoothie](https://github.com/hipstersmoothie))
1818 | - move utils around + add date to front-matters ([@hipstersmoothie](https://github.com/hipstersmoothie))
1819 | - add blog index ([@hipstersmoothie](https://github.com/hipstersmoothie))
1820 | - refactor to TS ([@hipstersmoothie](https://github.com/hipstersmoothie))
1821 | - make it pretty on mobile ([@hipstersmoothie](https://github.com/hipstersmoothie))
1822 | - default home page to home-page template ([@hipstersmoothie](https://github.com/hipstersmoothie))
1823 | - make overriding sidebar link simpler ([@hipstersmoothie](https://github.com/hipstersmoothie))
1824 | - customizable navbar ([@hipstersmoothie](https://github.com/hipstersmoothie))
1825 | - logo ([@hipstersmoothie](https://github.com/hipstersmoothie))
1826 | - customizable sidebar ([@hipstersmoothie](https://github.com/hipstersmoothie))
1827 | - sleeker layout ([@hipstersmoothie](https://github.com/hipstersmoothie))
1828 | - home page template ([@hipstersmoothie](https://github.com/hipstersmoothie))
1829 | - add ability to not have a home page ([@hipstersmoothie](https://github.com/hipstersmoothie))
1830 | - ensure sidebar links go to the right place ([@hipstersmoothie](https://github.com/hipstersmoothie))
1831 | - get some docs up ([@hipstersmoothie](https://github.com/hipstersmoothie))
1832 | - style the sidebar and page a little ([@hipstersmoothie](https://github.com/hipstersmoothie))
1833 | - less files needed bu user ([@hipstersmoothie](https://github.com/hipstersmoothie))
1834 | - factor out base overridable components ([@hipstersmoothie](https://github.com/hipstersmoothie))
1835 | - custom sidebar ([@hipstersmoothie](https://github.com/hipstersmoothie))
1836 | - make a lib ([@hipstersmoothie](https://github.com/hipstersmoothie))
1837 | - make require.context work from another DIR ([@hipstersmoothie](https://github.com/hipstersmoothie))
1838 | - dynimic blog post loading ([@hipstersmoothie](https://github.com/hipstersmoothie))
1839 | - determine layout based on file, default to docs layout for undefined ([@hipstersmoothie](https://github.com/hipstersmoothie))
1840 | - set up readme ([@hipstersmoothie](https://github.com/hipstersmoothie))
1841 | - make top level pages dynamic ([@hipstersmoothie](https://github.com/hipstersmoothie))
1842 | - dynamic sidebar ([@hipstersmoothie](https://github.com/hipstersmoothie))
1843 | - woah ([@hipstersmoothie](https://github.com/hipstersmoothie))
1844 | - add search ([@hipstersmoothie](https://github.com/hipstersmoothie))
1845 | - get mdx overrides working and the blog ([@hipstersmoothie](https://github.com/hipstersmoothie))
1846 | - init ([@hipstersmoothie](https://github.com/hipstersmoothie))
1847 |
1848 | #### Authors: 1
1849 |
1850 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
1851 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # next-ignite
2 |
3 | - add a blog just by adding a `blog/` folder and some mdx files in `pages/`
4 | - Add multiple top level docs sections just by adding more folders and mdx in `pages/`
5 | - Home Page (Break out into JS easy as hell)
6 | - Simple search (only work after a full production build)
7 | - Dynamically match `layouts` + add fallbacks based on routes
8 | - Customize the dark and light mode syntax highlighting. Use any VSCode or textmate theme.
9 |
10 | ## Getting Started
11 |
12 | ```bash
13 | yarn
14 | yarn build:lib
15 | yarn dev
16 | ```
17 |
18 | ## TODO
19 |
20 | - [ ] generate open graph images for docs and blog?
21 |
--------------------------------------------------------------------------------
/bin/ignite.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require("dotenv").config();
3 |
4 | const fs = require("fs");
5 | const path = require("path");
6 | const glob = require("fast-glob");
7 | const { app } = require("command-line-application");
8 | const { createServer } = require("http");
9 | const { parse } = require("url");
10 | const { execSync } = require("child_process");
11 | const next = require("next");
12 | const copy = require("copy-template-dir");
13 | const { getConfig } = require("../dist/cjs/utils/get-config");
14 | const { buildSitemap } = require("../dist/cjs/utils/sitemap");
15 | const { getTopLevelSections } = require("../dist/cjs/utils/docs-data");
16 | const { buildSearchIndex } = require("../dist/cjs/utils/build-search-index");
17 | const { buildRssFeed, test } = require("../dist/cjs/utils/build-rss-feed");
18 | const { purgeUnusedCss } = require("../dist/cjs/utils/purge-unused-css");
19 | const { generatePwaAssets } = require("../dist/cjs/utils/generate-pwa-assets");
20 |
21 | const buildNext = require("next/dist/build").default;
22 | const exportNext = require("next/dist/export").default;
23 |
24 | function getNextConfig() {
25 | try {
26 | const nextConfig = path.join(process.cwd(), "docs/next.config.js");
27 | return require(nextConfig);
28 | } catch (error) {}
29 | }
30 |
31 | const args = app({
32 | name: "ignite",
33 | description: "Flexible MDX documentation generator.",
34 | commands: [
35 | {
36 | name: "init",
37 | description: "Initialize an ignite-cli based docs site.",
38 | },
39 | {
40 | name: "dev",
41 | description: "Develop your documentation.",
42 | },
43 | {
44 | name: "build",
45 | description: "Build your documentation.",
46 | },
47 | {
48 | name: "deploy",
49 | description: "Deploy your documentation to GitHub Pages.",
50 | },
51 | ],
52 | });
53 |
54 | const run = () => {
55 | if (!args) {
56 | return;
57 | }
58 |
59 | if (args._command === "build") {
60 | process.env.NODE_ENV = "production";
61 | }
62 |
63 | if (args._command === "init") {
64 | const inDir = path.join(__dirname, "../template");
65 | const outDir = path.join(process.cwd(), "docs");
66 |
67 | copy(inDir, outDir, {}, (err, createdFiles) => {
68 | if (err) {
69 | throw err;
70 | }
71 |
72 | console.log("Initialized ignite documentation website!");
73 | });
74 | } else {
75 | const ignite = require("../next");
76 | const igniteConfig = getConfig();
77 | const nextConfig = getNextConfig();
78 | const { ignite: igniteFinalConfig, ...config } =
79 | igniteConfig && !nextConfig ? ignite(igniteConfig)() : nextConfig;
80 |
81 | if (args._command === "dev") {
82 | const docs = next({ dev: true, dir: "docs", conf: config });
83 | const handle = docs.getRequestHandler();
84 | const sections = getTopLevelSections(config.order);
85 |
86 | docs.prepare().then(() => {
87 | createServer((req, res) => {
88 | // Be sure to pass `true` as the second argument to `url.parse`.
89 | // This tells it to parse the query portion of the URL.
90 | const parsedUrl = parse(req.url, true);
91 | handle(req, res, parsedUrl);
92 | }).listen(3000, (err) => {
93 | if (err) {
94 | throw err;
95 | }
96 |
97 | console.log(`> Ready on http://localhost:3000/${sections[0]}`);
98 | buildSearchIndex("public");
99 | });
100 | });
101 | }
102 |
103 | if (args._command === "build") {
104 | const docsDir = path.resolve(path.join(process.cwd(), "docs"));
105 | const distDir = path.join(docsDir, ".next");
106 | const outdir = path.join(docsDir, "out");
107 |
108 | buildNext(docsDir, config)
109 | .then(() => exportNext(docsDir, { outdir }))
110 | .then(() => buildSearchIndex())
111 | .then(async () => {
112 | console.log("Export successful", 0);
113 | execSync(
114 | `touch ${path.resolve(
115 | path.join(process.cwd(), "docs/out/.nojekyll")
116 | )}`
117 | );
118 | buildSitemap();
119 | buildRssFeed(igniteFinalConfig);
120 | purgeUnusedCss(igniteFinalConfig);
121 |
122 | if (config.env.BUILD_PWA === "true") {
123 | fs.copyFileSync(
124 | path.join(distDir, "sw.js"),
125 | path.join(outdir, "sw.js")
126 | );
127 | const workbox = glob.sync(path.join(distDir, "workbox-*.js"));
128 |
129 | if (workbox[0]) {
130 | fs.copyFileSync(
131 | workbox[0],
132 | path.join(outdir, path.basename(workbox[0]))
133 | );
134 | }
135 |
136 | await generatePwaAssets(igniteFinalConfig);
137 | }
138 | })
139 | .catch((err) => {
140 | console.error("");
141 | console.error("> Build error occurred");
142 | console.log(err);
143 | });
144 | }
145 |
146 | if (args._command === "deploy") {
147 | try {
148 | execSync(
149 | 'npx push-dir --cleanup --dir=docs/out --branch=gh-pages --message="Update docs [skip ci]" --verbose'
150 | );
151 |
152 | console.log("Export successful");
153 | } catch (error) {
154 | console.log(error.stdout.toString());
155 | console.log(error.stderr.toString());
156 | }
157 | }
158 | }
159 | };
160 |
161 | run();
162 |
--------------------------------------------------------------------------------
/docs/css/syntax-highlighting-overrides.css:
--------------------------------------------------------------------------------
1 | .token.operator,
2 | .token.entity,
3 | .token.url,
4 | .language-css .token.string,
5 | .style .token.string {
6 | background: none;
7 | }
8 |
9 | * {
10 | text-shadow: none !important;
11 | }
12 |
--------------------------------------------------------------------------------
/docs/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/docs/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import type { AppProps } from "next/app";
3 | import { MDXProvider } from "@mdx-js/react";
4 | import { igniteComponents } from "next-ignite";
5 |
6 | import "next-ignite/dist/main.css";
7 | import "../css/syntax-highlighting-overrides.css";
8 |
9 | function MyApp({ Component, pageProps }: AppProps) {
10 | return (
11 |
12 |
13 |
14 | );
15 | }
16 |
17 | export default MyApp;
18 |
--------------------------------------------------------------------------------
/docs/pages/_document.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Document, { Html, Head, Main, NextScript } from "next/document";
3 | import { formatPath } from "next-ignite";
4 |
5 | class MyDocument extends Document {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
37 |
38 |
39 | );
40 | }
41 | }
42 |
43 | export default MyDocument;
44 |
--------------------------------------------------------------------------------
/docs/pages/blog.js:
--------------------------------------------------------------------------------
1 | import { BlogIndex } from "next-ignite";
2 |
3 | const Blog = () => ;
4 |
5 | export default Blog;
6 |
--------------------------------------------------------------------------------
/docs/pages/blog/first.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "My First Blog Post"
3 | author: Andrew lisowski
4 | email: lisowski54@gmail.com
5 | date: "Thu, 12 Mar 2020 23:00:02 -0700"
6 | ---
7 |
8 | Aenean faucibus dui at arcu dignissim, eu maximus neque consectetur.
9 | Cras urna nisi, lobortis ut ultrices facilisis, luctus ut magna.
10 | Fusce sit amet porttitor velit. Nullam eu placerat dui.
11 | In hac habitasse platea dictumst.
12 | Donec in diam quis nibh posuere porttitor a ut ipsum.
13 | Fusce eu consectetur turpis.
14 | Nulla accumsan ipsum a ipsum consectetur luctus.
15 |
16 | Some killer content.
17 |
--------------------------------------------------------------------------------
/docs/pages/blog/second.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "My Second Blog Post"
3 | author: Andrew lisowski
4 | email: lisowski54@gmail.com
5 | image: "https://images.unsplash.com/photo-1566386087068-55645996b234?crop=entropy&c…rgb&fit=crop&fm=jpg&h=500&ixid=eyJhcHBfaWQiOjF9&ixlib=rb-1.2.1&q=80&w=1950"
6 | ---
7 |
8 | Some better content. Explore more text inside of a blog post.
9 |
10 | ## Heading 2
11 |
12 | Some content.
13 |
14 | ### Heading 2.1
15 |
16 | More.
17 |
18 | ## Heading 3
19 |
20 | Here
21 |
--------------------------------------------------------------------------------
/docs/pages/docs/_sidebar.mdx:
--------------------------------------------------------------------------------
1 | Welcome
2 |
3 | - [Introduction](.)
4 | - [Getting Started](./getting-started)
5 | - [Configuration](./configuration)
6 | - [Using the CLI](./cli)
7 |
8 | ---
9 |
10 | Features
11 |
12 | - [Markdown Components](./features/markdown-components)
13 | - [Custom Sidebar](./features/custom-sidebar)
14 | - [Home Page](./features/home-page)
15 | - [Blog](./features/blog)
16 | - [Multi-Docs](./features/multi-docs)
17 |
18 | ---
19 |
20 | Advanced Features
21 |
22 | - [Layouts](./advanced-features/layouts)
23 | - [JavaScript Pages](./advanced-features/javascript-pages)
24 | - [Theming](./advanced-features/theming)
25 | - [Next.js Plugin](./advanced-features/next)
26 | - [Progressive Web App](./advanced-features/pwa)
27 |
--------------------------------------------------------------------------------
/docs/pages/docs/advanced-features/javascript-pages.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Writing Pages in JavaScript"
3 | description: "A guide to tapping into next-ignites layouts and component in javascript pages"
4 | ---
5 |
6 | Since `ignite` is just a small wrapper around Next.js you can easily break out into JavaScript or TypeScript.
7 | Simply change the file extension to the desired file type, rewrite the markdown to JSX, and you're done!
8 |
9 | > This is especially useful for the home page where you will probably want to
10 | > flex your design skills and really market your project.
11 |
12 | There are however a few considerations to make when you are doing this.
13 |
14 | ## Layouts
15 |
16 | `ignite` comes with a few [different layouts](./layouts) that render your mdx files.
17 | When you break out into JS `ignite` can no longer automatically assign a layout to your page.
18 | Luckily you can easily use any of these layouts in your JS pages too!
19 |
20 | ```js
21 | import { makeNavBarLayout } from "next-ignite";
22 |
23 | const NavBarLayout = makeNavBarLayout(
24 | // Provide any front-matter options to the layout here
25 | options
26 | );
27 |
28 | const MyPage = () => My Page ;
29 |
30 | export default MyPage;
31 | ```
32 |
33 | ## Styling
34 |
35 | To style your JS page to look just like the rest of your app you will need to use the components provided by the `MDXProvider`.
36 |
37 | Add the following usage of `useMDXComponents` to your code.
38 | This hooks provides all the customizable components that `ignite` uses.
39 | That includes everything from the base HTML components to the components that make up the sidebar and the navbar.
40 |
41 | ```tsx
42 | import { useMDXComponents } from "@mdx-js/react";
43 | import { makeNavBarLayout, Components } from "next-ignite";
44 |
45 | const NavBarLayout = makeNavBarLayout();
46 |
47 | const MyPage = () => {
48 | const components = useMDXComponents() as Components;
49 |
50 | return (
51 |
52 | My Page
53 |
54 | );
55 | };
56 |
57 | export default MyPage;
58 | ```
59 |
60 | ## Links
61 |
62 | Any link that you
63 |
64 | ```tsx
65 | import Link from "next/link";
66 | import { makeNavBarLayout, Components } from "next-ignite";
67 |
68 | const NavBarLayout = makeNavBarLayout();
69 |
70 | const MyPage = () => {
71 | const components = useMDXComponents() as Components;
72 |
73 | return (
74 |
75 | My Page
76 |
77 |
78 | Go somewhere
79 |
80 |
81 | );
82 | };
83 |
84 | export default MyPage;
85 | ```
86 |
87 | ## OpenGraphTags
88 |
89 | Make sure each page has rich open graph previews.
90 |
91 | ```tsx
92 | import Link from "next/link";
93 | import { makeNavBarLayout, Components, OpenGraphTags } from "next-ignite";
94 |
95 | const NavBarLayout = makeNavBarLayout();
96 |
97 | const MyPage = () => {
98 | const components = useMDXComponents() as Components;
99 |
100 | return (
101 | <>
102 |
107 |
108 | My Page
109 |
110 |
111 | Go somewhere
112 |
113 |
114 | >
115 | );
116 | };
117 |
118 | export default MyPage;
119 | ```
120 |
--------------------------------------------------------------------------------
/docs/pages/docs/advanced-features/layouts.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Using Layouts"
3 | description: "How to use all of the different the page layouts in your MDX"
4 | ---
5 |
6 | `ignite` comes with a few default layouts.
7 | For any of the pages these layouts are automatically assigned.
8 | If you wanted to you could use any layout for any page by specifying it in the front-matter for that page.
9 |
10 | ```yaml
11 | ---
12 | title: "My Page"
13 | layout: "docs"
14 | ---
15 |
16 | ```
17 |
18 | ## Layouts
19 |
20 | The following are all the default layouts included with `ignite`.
21 |
22 | ### `nav-bar`
23 |
24 | Renders the page with a NavBar above it.
25 |
26 | ```yaml
27 | ---
28 | layout: "nav-bar"
29 | ---
30 |
31 | ```
32 |
33 | ### `docs`
34 |
35 | Renders the page with a NavBar above it and the sidebar for the folder.
36 |
37 | ```yaml
38 | ---
39 | layout: "docs"
40 | ---
41 |
42 | ```
43 |
44 | ### `blog`
45 |
46 | Renders the page with a NavBar and a special blog post header.
47 |
48 | ```yaml
49 | ---
50 | layout: "blog"
51 | ---
52 |
53 | ```
54 |
55 | [Read about the options this layout supports](../features/blog#blog-post-format)
56 |
57 | ### `home-page`
58 |
59 | Renders the page with a NavBar and a special home page header.
60 |
61 | ```yaml
62 | ---
63 | layout: "blog"
64 | ---
65 |
66 | ```
67 |
68 | [Read about the options this layout supports](../features/home-page#mdx-features)
69 |
70 | ### TODO Adding Your Own Layouts
71 |
72 | ### TODO Automatic Layout Matching
73 |
--------------------------------------------------------------------------------
/docs/pages/docs/advanced-features/next.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Using next-ignite as a Next.js plugin"
3 | description: "Take full control of Next.js and use next-ignite like any other plugins"
4 | ---
5 |
6 | Most of `ignite`s features can be used as a plain Next.js plugin! :tada:
7 |
8 | What you loose:
9 |
10 | - can no longer use `.igniterc` file
11 |
12 | And not much else (we said it was a thin wrapper right :wink:)
13 |
14 | **`docs/next.config.js`:**
15 |
16 | ```js
17 | const withIgnite = require("next-ignite/next")({
18 | // your ignite options
19 | });
20 |
21 | module.exports = withIgnite();
22 | ```
23 |
24 | ## Options
25 |
26 | You can config `ignite` directly from your `next.config.js`.
27 | This is the same configuration present in your `.igniterc`.
28 | When using `ignite` as a Next.js plugin you config will not be loaded.
29 |
30 | To see the available configuration options visit the [configuration documentation](../configuration).
31 |
32 | ```js
33 | const withIgnite = require("next-ignite/next")({
34 | basePath: "pages",
35 | });
36 |
37 | module.exports = withIgnite();
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/pages/docs/advanced-features/pwa.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Creating a Progressive Web App"
3 | description: "Easily package you website as a PWA just by adding a manifest.json"
4 | ---
5 |
6 | To make your `next-ignite` website into a PWA do simply create a `docs/public/manifest.json`.
7 |
8 | You do not need `icons` or `start_url`, `next-ignite` handles that for you.
9 |
10 | ```json
11 | {
12 | "name": "next-ignite Docs",
13 | "short_name": "ignite",
14 | "description": "Fun docs site.",
15 | "theme_color": "#3b82f6",
16 | "background_color": "#fff",
17 | "dark_background_color": "#11151d",
18 | "display": "standalone",
19 | "orientation": "portrait"
20 | }
21 | ```
22 |
--------------------------------------------------------------------------------
/docs/pages/docs/advanced-features/theming.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Theming the Website"
3 | description: "Theme just the colors next-ignite uses or override any component in the UI"
4 | ---
5 |
6 | `ignite` provides two ways to theme:
7 |
8 | - Customize the colors => CSS variables
9 | - Customize the component used to render arbitrary HTML elements => MDX
10 |
11 | ## Color Theming
12 |
13 | `ignite` is uses [tailwind](https://tailwindcss.com/) so changing the colors for you website is super simple.
14 | All you have to do is set some CSS variables and `ignite` will use those colors.
15 |
16 | _Available Colors:_
17 |
18 | - primary (100-900) - The primary color for your app
19 | - gray (100-1000) - A gray that compliments the primary color
20 |
21 | Add a `style` block to your `pages/_document.js` that sets your desired colors.
22 |
23 | ```js
24 | import React from "react";
25 | import Document, { Html, Head, Main, NextScript } from "next/document";
26 |
27 | class MyDocument extends Document {
28 | render() {
29 | return (
30 |
31 |
33 |
40 |
41 |
42 |
43 |
44 | );
45 | }
46 | }
47 |
48 | export default MyDocument;
49 | ```
50 |
51 | If you're having trouble creating the full color ranges [try out this tool I made](https://hipstersmoothie.github.io/color-palette/).
52 | You can enter a `primary 500` color and it will generate a range for the primary and a complimentary gray.
53 |
54 | ## Component Theming
55 |
56 | `ignite` is uses [mdx](https://github.com/mdx-js/mdx) so it's incredibly simple to customize **any** component!
57 |
58 | ### Theming the Base Elements
59 |
60 | All you need to do is open up your `_app.js` and the your components to the `MDXProvider`.
61 |
62 | See the [full list of base elements](../features/markdown-components).
63 |
64 | ```js
65 | import React from "react";
66 | import App from "next/app";
67 | import { MDXProvider } from "@mdx-js/react";
68 | import { igniteComponents } from "next-ignite";
69 |
70 | // Import the css to style the docs
71 | import "ignite/dist/main.css";
72 |
73 | import { Anchor } from "../components/anchor";
74 | import { H1 } from "../components/h1";
75 |
76 | const components = {
77 | ...igniteComponents,
78 | // Easily override and base HTML component
79 | h1: H1,
80 | a: Anchor,
81 | };
82 |
83 | class MyApp extends App {
84 | render() {
85 | const { Component, pageProps } = this.props;
86 |
87 | return (
88 |
89 |
90 |
91 | );
92 | }
93 | }
94 |
95 | export default MyApp;
96 | ```
97 |
98 | ### Making a component
99 |
100 | When you are creating these component overrides, it is important to do this the right way.
101 | Two things you should consider are:
102 |
103 | 1. Applying the `className` properly
104 | 2. Spreading the rest of the props
105 |
106 | **Example `h1` Component:**
107 |
108 | ```js
109 | import React from "react";
110 | import makeClass from "clsx";
111 |
112 | const h1 = ({ className, ...props }) => (
113 |
122 | );
123 | ```
124 |
125 | ### Theming the rest
126 |
127 | In addition to being able to theme all the base components, `ignite` lets you theme all the components provided by `ignite`!
128 |
129 | This includes all the components that compose:
130 |
131 | - Sidebar
132 | - Navigation Bar
133 |
134 | Full list of themeable `ignite` components:
135 |
136 | - `Logo`
137 | - `NavBarWrapper`
138 | - `NavBar`
139 | - `NavBarItem`
140 | - `SearchInput`
141 | - `MobileMenuButton`
142 | - `Sidebar`
143 | - `SidebarItemWrapper`
144 | - `SidebarLink`
145 | - `SidebarTitle`
146 | - `SidebarDivider`
147 | - `SidebarList`
148 |
149 | When overriding these components please refer to [base implementations]() for available props.
150 |
--------------------------------------------------------------------------------
/docs/pages/docs/cli.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Using the `next-ignite` CLI
3 | description: "The commands you can run with next-ignite"
4 | ---
5 |
6 | The fastest way to start using `next-ignite` is through the command line interface (CLI) it ships with.
7 | The CLI basically just wraps Next.js's CLI and adds some defaults.
8 |
9 | ## Commands
10 |
11 | ### `Init`
12 |
13 | Initialize an ignite-cli based docs site.
14 |
15 | ```sh
16 | yarn init
17 | ```
18 |
19 | ### `dev`
20 |
21 | Start the development server.
22 |
23 | ```sh
24 | yarn dev
25 | ```
26 |
27 | ### `build`
28 |
29 | Build the website into static HTML files.
30 |
31 | ```sh
32 | yarn dev
33 | ```
34 |
35 | ### `deploy`
36 |
37 | Deploy your static HTML files to GitHub pages.
38 |
39 | ```sh
40 | yarn dev
41 | ```
42 |
--------------------------------------------------------------------------------
/docs/pages/docs/configuration.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuration
3 | description: "All of the configuration options and where next-ignite looks"
4 | ---
5 |
6 | For the most part you should not have to create a project specific configuration for you docs.
7 | If you do, the following documents all of the available options.
8 |
9 | ## Configuration File
10 |
11 | `ignite` uses [cosmiconfig](https://www.npmjs.com/package/cosmiconfig) to load its configuration file.
12 | We support all formats that the default `cosmiconfig` configuration supports.
13 |
14 | The two most commons ways to configure `ignite` is either through a json `.igniterc` at the root of your project:
15 |
16 | ```json
17 | {
18 | "name": "My Project"
19 | }
20 | ```
21 |
22 | or if you're project is in JavaScript, directly in the `package.json`:
23 |
24 | ```json
25 | {
26 | "name": "npm-package",
27 | "ignite": {
28 | "name": "My Project"
29 | }
30 | }
31 | ```
32 |
33 | ## Options
34 |
35 | ### Repo
36 |
37 | The repo that contains your project.
38 | This can be a short slug if on public GitHub.
39 |
40 | ```json
41 | {
42 | "repo": "hipstersmoothie/my-repo"
43 | }
44 | ```
45 |
46 | ### Name
47 |
48 | The name of your project.
49 | This value is used in multiple places in the docs.
50 |
51 | ```json
52 | {
53 | "name": "My Project"
54 | }
55 | ```
56 |
57 | ### URL
58 |
59 | The url you will be deploying to.
60 |
61 | ```json
62 | {
63 | "basePath": "https://my.com/pages/your-project"
64 | }
65 | ```
66 |
67 | ### Order
68 |
69 | Control the order of the top level section in the navbar.
70 | Each item in the array should be a name of one of your top-level documentation folders.
71 | Any unordered sections will be put after your provided order in alphabetical order.
72 |
73 | ```jsonc
74 | {
75 | // The Default
76 | "order": ["docs", "blog"]
77 | }
78 | ```
79 |
80 | ### HTML Urls
81 |
82 | Add `.html` to the end of each internal URL.
83 |
84 | ```jsonc
85 | {
86 | "htmlUrls": true
87 | }
88 | ```
89 |
90 | ### PurgeCSS
91 |
92 | By default `next-ignite` will purge CSS it doesn't use.
93 |
94 | You can turn off this behavior:
95 |
96 | ```jsonc
97 | {
98 | "purge": false
99 | }
100 | ```
101 |
102 | ## Remark and ReHype Plugins.
103 |
104 | You can provide plugins for the underlying markdown and html libraries we use to add more features.
105 |
106 | > NOTE: You can only specify these plugins in a JavaScript based configuration
107 |
108 | ```js
109 | const toc = require("rehype-toc");
110 | const withIgnite = require("next-ignite/next")({
111 | // your ignite options
112 | rehypePlugins: [toc],
113 | });
114 |
115 | module.exports = withIgnite();
116 | ```
117 |
118 | ## Syntax Theme
119 |
120 | You can change the theme for syntax highlighting in both light and dark mode.
121 |
122 | [See supported themes](https://github.com/shikijs/shiki/blob/master/docs/themes.md#literal-values);
123 |
124 | ```jsonc
125 | {
126 | "lightSyntaxTheme": "light-plus",
127 | "darkSyntaxTheme": "dark-plus"
128 | }
129 | ```
130 |
131 | You can also specify the theme as a path:
132 |
133 | ```jsonc
134 | {
135 | "lightSyntaxTheme": "./my-custom-theme.json"
136 | }
137 | ```
138 |
139 | or as JSON:
140 |
141 | ```jsonc
142 | {
143 | "lightSyntaxTheme": {
144 | // Theming values
145 | }
146 | }
147 | ```
148 |
149 | ## Files
150 |
151 | ## `docs/public/logo.png`
152 |
153 | The logo for your project.
154 |
155 | ## `docs/public/logo-dark.png`
156 |
157 | The logo for your project when the OS is in dark mode.
158 |
159 | ## `docs/public/images/favicon.*`
160 |
161 | The favicon for your project.
162 |
163 | ## `docs/public/images/favicon-dark.*`
164 |
165 | The favicon for your project when the OS is in dark mode.
166 |
--------------------------------------------------------------------------------
/docs/pages/docs/features/blog.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Creating a Blog"
3 | description: "How to add a blog to your website"
4 | ---
5 |
6 | Adding a blog with `ignite` is super easy.
7 | All you have to do is start adding `.mdx` files to a folder names `pages/blog` and set up the blog index page.
8 |
9 | ## Blog Index Page
10 |
11 | Create a file in your `pages/` folder named `blog.js`.
12 | This simplest way to get a blog index running is by using the sample component `ignite` provides
13 |
14 | ```js
15 | import { BlogIndex } from "next-ignite";
16 |
17 | const Blog = () => ;
18 |
19 | export default Blog;
20 | ```
21 |
22 | If you want more control of what this page looks like you can use the lower level functions `ignite` provides.
23 |
24 | In this file add the following to render a simple list of your blog posts:
25 |
26 | ```js
27 | import Link from "next/link";
28 | // getBlogPosts will return the blogs in reverse creation order
29 | import { getBlogPosts, makeNavBarLayout } from "next-ignite";
30 | import { useMDXComponents } from "@mdx-js/react";
31 |
32 | // Make a layout with the navbar at the
33 | const NavBarLayout = makeNavBarLayout();
34 | // Get all the blog posts
35 | const posts = getBlogPosts();
36 |
37 | const Blog = () => {
38 | // Make sure to use the components defined for you docs!
39 | const components = useMDXComponents();
40 |
41 | return (
42 |
43 | Blog
44 |
45 |
46 | {posts.map((page) => (
47 |
48 |
49 | {page.title}
50 |
51 |
52 | ))}
53 |
54 |
55 | );
56 | };
57 |
58 | export default Blog;
59 | ```
60 |
61 | Once this is setup you're ready to start writing blog posts! :tada:
62 |
63 | ## Blog Post Format
64 |
65 | A blog post is just another `.mdx` file, but it has a few more front-matter features.
66 |
67 | You should always include a title.
68 |
69 | ```yaml
70 | ---
71 | title: "My First Blog Post"
72 | ---
73 |
74 | ```
75 |
76 | ### author
77 |
78 | You can include an author in the blog post, otherwise this information will get pull from the commit.
79 | Include an email to display an avatar using gravatar.
80 |
81 | ```yaml
82 | ---
83 | title: "My First Blog Post"
84 | author: "Andrew Lisowski"
85 | email: "lisowski54@gmail.com"
86 | ---
87 |
88 | ```
89 |
90 | ### date
91 |
92 | Specify the date the post was created.
93 | If not supplied this information is pulled from the commit date.
94 |
95 | ```yaml
96 | ---
97 | date: "Thu, 12 Mar 2020 23:00:02 -0700"
98 | ---
99 |
100 | ```
101 |
102 | ### color
103 |
104 | A color to use as the backdrop for a post
105 |
106 | ```yaml
107 | ---
108 | color: "red"
109 | ---
110 |
111 | ```
112 |
113 | ### image
114 |
115 | Instead of a color you can display an image as the backdrop.
116 |
117 | ```yaml
118 | ---
119 | image: "http://image.com/example.png"
120 | ---
121 |
122 | ```
123 |
124 | ## Comments
125 |
126 | To add comments to your blog [first sign for any plan with disqus](https://disqus.com/) and then add the following to your `_document.js`.
127 |
128 | ```js
129 | import React from "react";
130 | import Document, { Html, Head, Main, NextScript } from "next/document";
131 |
132 | class MyDocument extends Document {
133 | render() {
134 | return (
135 |
136 |
139 |
140 |
141 |
162 |
163 |
164 | );
165 | }
166 | }
167 |
168 | export default MyDocument;
169 | ```
170 |
--------------------------------------------------------------------------------
/docs/pages/docs/features/custom-sidebar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Customizing the Sidebar"
3 | description: "Create detailed sidebar definitions to take full control of it's content, either in JavaScript or MDX"
4 | ---
5 |
6 | While it's cool you don't _have to_ configure a Sidebar, you'll probably quickly find that you want some order.
7 | Luckily `ignite` makes this super easy.
8 | All you have to do is create a file `_sidebar.md` inside `pages/docs` and start organizing you docs.
9 |
10 | This can be as simple as a list of links:
11 |
12 | ```md
13 |
14 |
15 | - [Introduction](.)
16 | - [Getting Started](./getting-started)
17 | ```
18 |
19 | ## Titles
20 |
21 | You can add a title between groups of links
22 |
23 | ```md
24 | Welcome
25 |
26 | - [Introduction](.)
27 | - [Getting Started](./getting-started)
28 |
29 | Features
30 |
31 | - [Custom Sidebar](./features/custom-sidebar)
32 | ```
33 |
34 | ## Dividers
35 |
36 | Separate sections of the sidebar even further.
37 |
38 | ```md
39 | Welcome
40 |
41 | - [Introduction](.)
42 | - [Getting Started](./getting-started)
43 |
44 | ---
45 |
46 | Features
47 |
48 | - [Custom Sidebar](./features/custom-sidebar)
49 | ```
50 |
--------------------------------------------------------------------------------
/docs/pages/docs/features/home-page.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Adding a Home Page"
3 | description: "Every website needs a fancy marketing page."
4 | ---
5 |
6 | A home/cover page is useful to give a quick overview of the thing you're documenting.
7 | This is a great way to market your project.
8 | Detailed technical documentation is great, but it's helpful to also include a higher level intro that sells new users.
9 |
10 | With `ignite` all you have to do to achieve this is create and `index.mdx` in your page folder.
11 | If mdx isn't enough to write this page just make it a JavaScript or TypeScript file.
12 | You'll be able to fully control what your home page looks like! :partying_face:
13 |
14 | [Read more about fully JavaScript pages.](../advanced-features/javascript-pages)
15 |
16 | ## MDX Features
17 |
18 | If you write your home page using mdx there are a few options you can use to customize the `home-page` layout.
19 |
20 | ### Title
21 |
22 | The layout for the home page template will display the title of your project by default.
23 | To override this specify a different title in the front-matter.
24 |
25 | ```yaml
26 | ---
27 | title: "Some other title"
28 | ---
29 |
30 | ```
31 |
32 | ### Tagline
33 |
34 | To display a tagline below the name of you project use the `tagline` property in the front-matter.
35 |
36 | ```yaml
37 | ---
38 | tagline: "The most flexible documenting website you've ever used"
39 | ---
40 |
41 | ```
42 |
43 | ### Color
44 |
45 | Change the color of the main here and the `Getting Started` button
46 |
47 | ```yaml
48 | ---
49 | color: "red"
50 | ---
51 |
52 | ```
53 |
--------------------------------------------------------------------------------
/docs/pages/docs/features/markdown-components.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Included Markdown Components"
3 | description: "All of the default markdown tags next-ignite styles. You can theme all of these!"
4 | ---
5 |
6 | `ignite` styles all of the default markdown components. [Read how to customize.](../advanced-features/theming)
7 |
8 | | Tag | Syntax |
9 | | ------------ | --------------------------------------------------- |
10 | | `h1` | `#` |
11 | | `h2` | `##` |
12 | | `h3` | `###` |
13 | | `h4` | `####` |
14 | | `h5` | `#####` |
15 | | `h6` | `######` |
16 | | `p` | |
17 | | `a` | `` or `[MDX](https://mdxjs.com)` |
18 | | `em` | `_emphasis_` |
19 | | `strong` | `**strong**` |
20 | | `delete` | `~~strikethrough~~` |
21 | | `inlineCode` | `` `inlineCode` `` |
22 | | `pre` | (Only used when theming) |
23 | | `code` | \`\`\`code\`\`\` |
24 | | `blockquote` | `>` |
25 | | `img` | `` |
26 | | `ul` | `-` |
27 | | `ol` | Ordered `1.` |
28 | | `li` | List |
29 | | `hr` | `---` or `***` |
30 | | `table` | |
31 | | `thead` | Table |
32 | | `tbody` | Table |
33 | | `tr` | Table |
34 | | `td`/`th` | Table |
35 |
36 | ---
37 |
38 |
39 |
40 | See Example Rendering
41 |
42 |
43 | # Heading Level 1 (`abcde`)
44 |
45 | ## Heading Level 2 (`abcde`)
46 |
47 | ### Heading Level 3 (`abcde`)
48 |
49 | #### Heading Level 4 (`abcde`)
50 |
51 | ##### Heading Level 5 (`abcde`)
52 |
53 | ###### Heading Level 6 (`abcde`)
54 |
55 | This is a paragraph of text
56 |
57 | [a link](./multi-docs)
58 |
59 | _Emphasized text_
60 |
61 | **Strong text**
62 |
63 | ~~Strikethrough text~~
64 |
65 | `inline code`
66 |
67 | ```md
68 | # A block of code with a really really really really really really really really really really really really really long line of text
69 | ```
70 |
71 | > A block quote
72 |
73 |
74 |
75 | 
76 |
77 |
78 |
79 | - An Example
80 | - Of an unordered
81 | - List
82 |
83 | 1. An Example
84 | 2. Of an ordered
85 | 3. List
86 |
87 | ---
88 |
89 | | Title | Descriptions |
90 | | ----- | ------------ |
91 | | foo | bar |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/docs/pages/docs/features/multi-docs.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Multiple Top-Level Sections"
3 | description: "HOw to have multiple top-level sections in your docs site"
4 | ---
5 |
6 | Many times when you're writing docs you may need different sections with a completely different sidebar.
7 | To accomplish this in `ignite` simply add more folders to your `pages/` folder.
8 | Each folder will be turned into a new top-level section in the navbar.
9 | The folder name is converted into a name for the navigation item.
10 |
11 | For example, to add a new top level section called "Plugin Authoring" you would create the following folder structure.
12 |
13 | ```bash
14 | 📦docs
15 | ┣ 📂pages
16 | ┃ ┣ 📂docs
17 | ┃ ┃ ┣ index.mdx
18 | ┃ ┣ 📂plugin-authoring
19 | ┃ ┃ ┣ index.mdx
20 | ┃ ┣ 404.js
21 | ┃ ┣ _app.js
22 | ```
23 |
24 | By default the sidebar is in alphabetical order.
25 | To change this add a [custom sidebar](./custom-sidebar).
26 |
--------------------------------------------------------------------------------
/docs/pages/docs/getting-started.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Getting Started"
3 | description: "A quick start guide to getting set up with next-ignite"
4 | ---
5 |
6 | `ignite` is distributed on `npm`.
7 |
8 | ```bash
9 | npm i --save-dev ignite
10 | # or
11 | yarn add -d ignite
12 | ```
13 |
14 | ## Setup
15 |
16 | Getting setup with `ignite` require you to create a few files in addition to all of your actual documentation.
17 |
18 | ### Quick
19 |
20 | To quickly get started using `ignite` just run one of the following commands.
21 | This will setup a minimal docs folder so you can get straight to documenting.
22 |
23 | ```bash
24 | # using npm
25 | npx ignite init
26 |
27 | # using yarn
28 | yarn ignite init
29 | ```
30 |
31 | ### Manual
32 |
33 | First create a folder named `docs` and structure it to resemble the following.
34 |
35 | ```bash
36 | 📦docs
37 | ┣ 📂pages
38 | ┃ ┣ 📂docs
39 | ┃ ┃ ┣ index.mdx
40 | ┃ ┣ _app.js
41 | ```
42 |
43 | You **must have**:
44 |
45 | - `pages/_app.js`
46 | - `pages/docs/index.mdx`
47 |
48 | Add the following to your `.gitignore`.
49 |
50 | ```
51 | .next
52 | .mdx-data
53 | docs/public/search-index.json
54 | ```
55 |
56 | #### `_app.tsx`
57 |
58 | You need to at least do the following:
59 |
60 | 1. Import `MDXProvider`, `igniteComponents`, and combine the at the root of the app
61 | 2. Import `ignite`'s css
62 |
63 | ```js
64 | import React from "react";
65 | import App from "next/app";
66 | import { MDXProvider } from "@mdx-js/react";
67 | import { igniteComponents } from "next-ignite";
68 |
69 | // Import the css to style the docs
70 | import "ignite/dist/main.css";
71 |
72 | class MyApp extends App {
73 | render() {
74 | const { Component, pageProps } = this.props;
75 |
76 | return (
77 |
78 |
79 |
80 | );
81 | }
82 | }
83 |
84 | export default MyApp;
85 | ```
86 |
87 | #### Start writing docs :tada:
88 |
89 | Now that you have all that set up you can start writing documentation!
90 | All you need to do is start adding `.mdx` files to `pages/docs`.
91 | A good one to start with is `pages/docs/index.mdx` since this will be the first page shown to the user.
92 |
93 | **`pages/docs/index.mdx`:**
94 |
95 | ```mdx
96 | ---
97 | title: "My Introduction"
98 | ---
99 |
100 | The start of my amazing documentation.
101 | ```
102 |
103 | Now start up the development server:
104 |
105 | ```sh
106 | yarn ignite dev
107 | ```
108 |
109 | Once it's done loading you should see that that your documentation has loaded and `ignite` automatically created a sidebar for you! :astonished:
110 |
111 | ## Explore More Features
112 |
113 | `ignite` tries to be as flexible as possible, so many parts are customizable.
114 | Explore the documentation to find all the documentation site :candy: we include.
115 |
116 | **_Highlights:_**
117 |
118 | :star: [Customize the sidebar](./features/custom-sidebar)
119 |
120 | :star: [Home/Cover Page](./features/home-page)
121 |
122 | :star: [Set up a blog](./features/blog)
123 |
124 | :star: [Multiple top-Level documentation sections](./features/multi-docs)
125 |
126 | :star: [Use JavaScript for any page](./advanced-features/javascript-pages)
127 |
--------------------------------------------------------------------------------
/docs/pages/docs/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Welcome"
3 | description: "Bend your docs to your will and document anything with ease"
4 | ---
5 |
6 | > Bend your docs to your will and document anything with ease.
7 |
8 | `ignite` is a command line application (CLI) for creating super flexible documentation website in MDX and [react](https://reactjs.org/).
9 | It takes care of the boring parts of setting up a documentation website so you can get straight to writing amazing docs!
10 |
11 | `ignite` is a thin wrapper around Next.js and `next-mdx-enhanced`.
12 |
13 | ## Features
14 |
15 | 🏗 Add multiple top level docs sections just by adding more folders and mdx in `pages/`
16 |
17 | 🎯 Add a blog just by adding a `blog/` folder and some mdx files in `pages/`
18 |
19 | 💅🏼 Overwrite any HTML element and render the site how you want to
20 |
21 | 📖 Home Page (Break out into JS easy as hell)
22 |
23 | 🧸 Simple search (only work after a full production build)
24 |
25 | 👮🏼♀️ Route based layouts
26 |
27 | ## Example
28 |
29 | Working with `ignite` is super simple!
30 | All you need to do is start adding `.mdx` files to your docs folder!
31 |
32 | **`docs/pages/docs/new-page.mdx`:**
33 |
34 | ```mdx
35 | ---
36 | title: "My Page"
37 | ---
38 |
39 | With some killer content! :tada:
40 | ```
41 |
42 | If you don't have a defined `_sidebar.mdx` this will automatically show up on your website!
43 | You'll most likely create a `_sidebar.mdx` if you want to define the order of your docs in the sidebar.
44 |
45 | **`docs/pages/docs/_sidebar.mdx`:**
46 |
47 | ```mdx
48 | - [Introduction](./)
49 | - [My Page](./my-page)
50 | ```
51 |
--------------------------------------------------------------------------------
/docs/pages/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | tagline: "The most flexible documentation website you've ever used."
3 | cta: "Check out the docs"
4 | ---
5 |
6 | `ignite` is a thin wrapper around `next.js` and `next-mdx-enhanced`.
7 | It is essentially two things:
8 |
9 | - A CLI for using `ignite` as a documentation generator
10 | - A convention and a set of functions. The `ignite` package exports everything you need to use it in any `next.js` application!
11 |
--------------------------------------------------------------------------------
/docs/public/images/favicon-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hipstersmoothie/next-ignite/d3859d57f1669951c56d48109811bd36b4258d89/docs/public/images/favicon-dark.png
--------------------------------------------------------------------------------
/docs/public/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hipstersmoothie/next-ignite/d3859d57f1669951c56d48109811bd36b4258d89/docs/public/images/favicon.ico
--------------------------------------------------------------------------------
/docs/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-ignite Docs",
3 | "short_name": "ignite",
4 | "theme_color": "#11151d",
5 | "background_color": "#fff",
6 | "dark_background_color": "#11151d",
7 | "description": "The documentation for using next-ignite.",
8 | "display": "standalone",
9 | "orientation": "portrait"
10 | }
--------------------------------------------------------------------------------
/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/next.d.ts:
--------------------------------------------------------------------------------
1 | import igniteNextPlugin from "./dist/next";
2 | export = igniteNextPlugin;
3 |
--------------------------------------------------------------------------------
/next.js:
--------------------------------------------------------------------------------
1 | module.exports = require("./dist/cjs/next").default;
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-ignite",
3 | "version": "0.10.11",
4 | "bin": {
5 | "ignite": "bin/ignite.js"
6 | },
7 | "main": "./dist/cjs/index.js",
8 | "module": "./dist/esm/index.js",
9 | "types": "./dist",
10 | "repository": "hipstersmoothie/next-ignite",
11 | "author": "Andrew Lisowski ",
12 | "scripts": {
13 | "dev": "yarn ignite dev",
14 | "build:lib": "ds build",
15 | "ignite": "./bin/ignite.js",
16 | "build:docs": "yarn ignite build",
17 | "release": "auto shipit"
18 | },
19 | "publishConfig": {
20 | "registry": "https://registry.npmjs.org"
21 | },
22 | "files": [
23 | "dist",
24 | "src",
25 | "bin",
26 | "next.js",
27 | "next.d.ts",
28 | "template"
29 | ],
30 | "dependencies": {
31 | "@babel/helper-call-delegate": "^7.12.1",
32 | "@next/bundle-analyzer": "^9.4.0",
33 | "@reach/skip-nav": "^0.12.1",
34 | "@react-hook/passive-layout-effect": "^1.2.0",
35 | "@tailwindcss/postcss7-compat": "^2.0.2",
36 | "@types/body-scroll-lock": "^2.6.1",
37 | "body-scroll-lock": "^3.1.5",
38 | "cheerio": "^1.0.0-rc.5",
39 | "clsx": "^1.1.0",
40 | "command-line-application": "^0.9.6",
41 | "copy-template-dir": "^1.4.0",
42 | "cosmiconfig": "^6.0.0",
43 | "dotenv": "^8.2.0",
44 | "fast-copy": "^2.1.1",
45 | "fast-glob": "^3.2.2",
46 | "feed": "^4.2.1",
47 | "gravatar": "^1.8.0",
48 | "hast-util-to-string": "^1.0.4",
49 | "markdown-to-jsx": "^7.1.1",
50 | "next": "^10.0.5",
51 | "next-mdx-enhanced": "^4.0.0",
52 | "next-prefixed": "^0.0.11",
53 | "next-pwa": "^5.0.4",
54 | "nextjs-sitemap-generator": "^1.0.0",
55 | "parse-github-url": "^1.0.2",
56 | "pretty-bytes": "^5.5.0",
57 | "purgecss": "^3.1.3",
58 | "push-dir": "^0.4.1",
59 | "pwa-asset-generator": "^4.1.1",
60 | "react": "16.13.0",
61 | "react-dom": "16.13.0",
62 | "react-merge-refs": "^1.1.0",
63 | "rehype": "^9.0.1",
64 | "rehype-accessible-emojis": "^0.3.2",
65 | "rehype-autolink-headings": "^3.0.0",
66 | "rehype-shiki-reloaded": "^0.0.10",
67 | "rehype-slug": "^3.0.0",
68 | "remark-emoji": "^2.0.2",
69 | "scroll-lock": "^2.1.4",
70 | "shiki": "^0.9.2",
71 | "shiki-languages": "^0.2.7",
72 | "tailwindcss": "npm:@tailwindcss/postcss7-compat",
73 | "title-case": "^3.0.2",
74 | "unist-builder": "^2.0.3",
75 | "unist-util-visit": "^2.0.3",
76 | "url-join": "^4.0.1",
77 | "use-click-outside": "^2.0.0",
78 | "use-debounce": "^5.2.0"
79 | },
80 | "devDependencies": {
81 | "@auto-it/gh-pages": "^10.16.5",
82 | "@design-systems/cli": "^2.7.3",
83 | "@types/gravatar": "^1.8.1",
84 | "@types/mdx-js__react": "^1.5.1",
85 | "@types/url-join": "^4.0.0",
86 | "auto": "^10.16.5",
87 | "autoprefixer": "^9.7.4",
88 | "next-ignite": "link:./",
89 | "postcss-import": "^12.0.1",
90 | "postcss-nested": "^4.2.1",
91 | "prettier": "^2.0.5"
92 | },
93 | "ignite": {
94 | "repo": "hipstersmoothie/next-ignite",
95 | "url": "https://hipstersmoothie.github.io/next-ignite",
96 | "description": "The documentation for next-ignite"
97 | },
98 | "auto": {
99 | "plugins": [
100 | "npm",
101 | [
102 | "gh-pages",
103 | {
104 | "buildCommand": "npm run build:docs",
105 | "dir": "./docs/out"
106 | }
107 | ]
108 | ]
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | "postcss-import": {},
4 | tailwindcss: {},
5 | "postcss-nested": {},
6 | autoprefixer: {},
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/avatar.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import gravatar from "gravatar";
3 | import makeClass from "clsx";
4 |
5 | interface AvatarProps {
6 | email?: string;
7 | className?: string;
8 | size?: number;
9 | }
10 |
11 | const Avatar = ({ email, className, size = 12 }: AvatarProps) => {
12 | if (!email) {
13 | return null;
14 | }
15 |
16 | return (
17 |
26 | );
27 | };
28 |
29 | export default Avatar;
30 |
--------------------------------------------------------------------------------
/src/components/blog-index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import Head from "next/head";
4 | import { useMDXComponents } from "@mdx-js/react";
5 | import makeClass from "clsx";
6 | import Markdown from "markdown-to-jsx";
7 |
8 | import getBlogPosts from "../utils/get-blog-posts";
9 | import NavBarLayout from "../layouts/nav-bar";
10 | import Avatar from "./avatar";
11 | import { postFixHTML } from "../utils/format-path";
12 |
13 | const posts = getBlogPosts();
14 | const dateFormat = new Intl.DateTimeFormat("default", {
15 | year: "numeric",
16 | month: "short",
17 | day: "numeric",
18 | });
19 |
20 | const MarkdownPreview = ({ page }) => {
21 | const components = useMDXComponents();
22 |
23 | return (
24 |
33 | {page.description}
34 |
35 | );
36 | };
37 |
38 | const SmallCard = ({ page }) => {
39 | return (
40 |
47 |
48 |
49 |
50 |
56 | {page.title}
57 |
58 | {page.description && (
59 |
69 | )}
70 |
71 |
72 |
78 | {page.email && (
79 |
80 | )}
81 |
82 |
83 | {page.author &&
{page.author}
}
84 |
85 |
86 | {dateFormat.format(new Date(page.date))}
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | );
95 | };
96 |
97 | const BigCard = ({ page }) => {
98 | return (
99 |
108 |
109 |
110 |
111 |
112 |
116 |
122 | {page.title}
123 |
124 |
125 | {page.description && (
126 |
127 |
128 |
129 | )}
130 |
131 |
132 |
133 | {page.email && (
134 |
135 | )}
136 |
137 |
138 | {page.author &&
{page.author}
}
139 |
140 |
141 | {dateFormat.format(new Date(page.date))}
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | );
150 | };
151 |
152 | interface BlogIndexProps {
153 | /** The color of the header */
154 | color?: string;
155 | }
156 |
157 | export default ({ color = "primary" }: BlogIndexProps) => {
158 | const components = useMDXComponents();
159 |
160 | return (
161 |
162 |
163 | {process.env.PROJECT_NAME} Blog
164 |
165 |
166 |
167 |
168 | Blog
169 |
170 |
171 |
172 | = 2 && "md:grid-cols-2",
176 | posts.length >= 3 && "lg:grid-cols-3",
177 | "lg:max-w-6xl lg:mx-auto lg:mt-16"
178 | )}
179 | >
180 | {posts.map((page, index) => {
181 | const isBigCard = page.image && index === 0;
182 |
183 | return (
184 |
191 |
192 |
193 | {isBigCard ? (
194 |
195 | ) : (
196 |
197 | )}
198 |
199 |
200 |
201 | );
202 | })}
203 |
204 |
205 | );
206 | };
207 |
--------------------------------------------------------------------------------
/src/components/mdx-components.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import makeClass from "clsx";
3 | import Link from "next/link";
4 | import mergeRefs from "react-merge-refs";
5 | import { useRouter } from "next/router";
6 | import useClickOutside from "use-click-outside";
7 | import join from "url-join";
8 | import { useDebouncedCallback } from "use-debounce";
9 | import { disableBodyScroll, clearAllBodyScrollLocks } from "body-scroll-lock";
10 |
11 | import { MDXProviderComponents } from "@mdx-js/react";
12 | import { prefixURL } from "next-prefixed";
13 | import useLayoutEffect from "@react-hook/passive-layout-effect";
14 | import { postFixHTML } from "../utils/format-path";
15 |
16 | export type Element<
17 | T extends keyof JSX.IntrinsicElements
18 | > = React.PropsWithoutRef;
19 |
20 | const sidebarScrollPositionKey = "IGNITE_PAGE_POSITION";
21 |
22 | interface MobileMenuButtonProps {
23 | open: boolean;
24 | setOpen: (newOpen: boolean) => void;
25 | }
26 |
27 | /** The button that opens the menu for mobile screen sizes */
28 | const MobileMenuButton = ({
29 | open,
30 | setOpen,
31 | className,
32 | ...props
33 | }: MobileMenuButtonProps & Element<"button">) => (
34 | setOpen(!open)}
41 | {...props}
42 | >
43 | {open ? (
44 |
49 |
50 |
51 | ) : (
52 |
57 |
58 |
59 | )}
60 |
61 | );
62 |
63 | /** The logo in the navbar */
64 | const Logo = React.forwardRef(
65 | (
66 | { className, ...props }: Element<"a">,
67 | ref: React.Ref
68 | ) => (
69 |
80 |
81 |
86 |
91 |
92 |
93 | {process.env.PROJECT_NAME}
94 |
95 |
96 | )
97 | );
98 |
99 | interface MatchHighlightProps {
100 | children: string;
101 | term: string;
102 | }
103 |
104 | const MatchHighlight = ({ children, term }: MatchHighlightProps) => {
105 | const highlighted = React.useMemo(() => {
106 | let remaining = children;
107 | let content = [];
108 | const termRegex = new RegExp(term, "i");
109 |
110 | if (!term) {
111 | return remaining;
112 | }
113 |
114 | while (remaining.match(termRegex)) {
115 | const start = remaining.toLowerCase().indexOf(term.toLowerCase());
116 | const end = start + term.length;
117 |
118 | content.push(remaining.slice(0, start));
119 | content.push(
120 |
121 | {remaining.slice(start, end)}
122 |
123 | );
124 |
125 | remaining = remaining.slice(end);
126 | }
127 |
128 | content.push(remaining);
129 |
130 | return content;
131 | }, [children, term]);
132 |
133 | return <>{highlighted}>;
134 | };
135 |
136 | /** The component used to search the mdx. */
137 | const SearchInput = React.forwardRef(
138 | (
139 | { className, ...props }: Element<"input">,
140 | ref: React.Ref
141 | ) => {
142 | const router = useRouter();
143 |
144 | let lastLvl0: string | undefined;
145 | const data = React.useRef([]);
146 | const resultsRef = React.useRef();
147 | const innerRef = React.useRef();
148 | const [current, currentSet] = React.useState(0);
149 | const [hasInteracted, hasInteractedSet] = React.useState(false);
150 | const [term, termSet] = React.useState("");
151 | const [search, searchSet] = React.useState("");
152 | const [showResults, showResultsSet] = React.useState(false);
153 | const debouncedSearchSet = useDebouncedCallback(() => {
154 | showResultsSet(Boolean(term));
155 | searchSet(term);
156 |
157 | if (resultsRef.current) {
158 | disableBodyScroll(resultsRef.current);
159 | }
160 | }, 200);
161 |
162 | const normalizedSearch = search.toLowerCase();
163 | const matchingResults = React.useMemo(() => {
164 | return data.current
165 | .filter((result) => {
166 | const matchedPath = result.path[result.path.length - 1]
167 | .toLowerCase()
168 | .includes(normalizedSearch);
169 | const matchedContent = result.content
170 | .toLowerCase()
171 | .includes(normalizedSearch);
172 |
173 | return matchedPath || matchedContent;
174 | })
175 | .sort((a, b) => {
176 | const getWeight = (n) => {
177 | const contentMatch = n.content
178 | .toLowerCase()
179 | .includes(normalizedSearch)
180 | ? 1
181 | : 0;
182 | const pathMatch = n.path.filter((p) =>
183 | p.toLowerCase().includes(normalizedSearch)
184 | ).length;
185 |
186 | return contentMatch + pathMatch;
187 | };
188 |
189 | return getWeight(b) - getWeight(a);
190 | });
191 | }, [search]);
192 |
193 | useClickOutside(innerRef, () => showResultsSet(false));
194 |
195 | React.useEffect(() => {
196 | fetch(join(process.env.BASE_PATH, "search-index.json"))
197 | .then((res) => res.text())
198 | .then((text) => (data.current = JSON.parse(text)));
199 | }, []);
200 |
201 | React.useEffect(() => {
202 | const el = document.querySelector("[aria-selected=true");
203 |
204 | if (el) {
205 | el.scrollIntoView({ block: "nearest" });
206 | }
207 | }, [current]);
208 |
209 | React.useEffect(() => {
210 | if (!showResults || !search) {
211 | console.log("enable");
212 | clearAllBodyScrollLocks();
213 | }
214 | }, [showResults, search]);
215 |
216 | return (
217 | {
221 | if (e.key === "Escape") {
222 | showResultsSet(false);
223 | }
224 |
225 | if (e.key === "Tab" || e.key === "Enter") {
226 | if (search && showResults) {
227 | router.push(postFixHTML(`/${matchingResults[current].url}`));
228 | e.preventDefault();
229 | }
230 |
231 | showResultsSet(false);
232 | }
233 |
234 | if (e.key === "ArrowDown") {
235 | currentSet(Math.min(matchingResults.length - 1, current + 1));
236 | hasInteractedSet(true);
237 | e.preventDefault();
238 | }
239 |
240 | if (e.key === "ArrowUp") {
241 | currentSet(Math.max(0, current - 1));
242 | hasInteractedSet(true);
243 | e.preventDefault();
244 | }
245 | }}
246 | >
247 |
248 |
{
265 | termSet(e.target.value);
266 | debouncedSearchSet.callback();
267 | }}
268 | {...props}
269 | />
270 |
271 | {search && (
272 |
{
279 | searchSet("");
280 | termSet("");
281 | showResultsSet(false);
282 | clearAllBodyScrollLocks();
283 | }}
284 | >
285 |
292 |
293 |
294 |
295 | )}
296 |
297 |
298 | {showResults && search && (
299 |
hasInteractedSet(true)}
307 | >
308 | {matchingResults.length ? (
309 | matchingResults.map((item, index) => {
310 | const contentIndex = item.content
311 | .toLowerCase()
312 | .indexOf(normalizedSearch);
313 | const contentStart = Math.max(0, contentIndex - 40);
314 | const contentEnd = Math.min(
315 | item.content.length,
316 | contentIndex + search.length + 40
317 | );
318 | const isSelected =
319 | (index === 0 && !hasInteracted) || index === current;
320 | const isGrouped = lastLvl0 === item.path[0];
321 |
322 | lastLvl0 = item.path[0];
323 |
324 | return (
325 |
379 | );
380 | })
381 | ) : (
382 |
383 | No match results for search{" "}
384 | "{search}" !
385 |
386 | )}
387 |
388 | )}
389 |
390 | );
391 | }
392 | );
393 |
394 | /** The component used to render the wrapper around the navbar */
395 | const NavBarWrapper = ({ className, ...props }: Element<"div">) => (
396 |
404 | );
405 |
406 | /** The component used to render the navbar */
407 | const NavBar = ({ className, ...props }: Element<"div">) => (
408 |
415 | );
416 |
417 | /** The component used to render a top-level navigation item */
418 | const NavBarItem = React.forwardRef(
419 | (
420 | { className, children, ...props }: Element<"a">,
421 | ref: React.Ref
422 | ) => (
423 |
434 | {children}
435 |
436 | )
437 | );
438 |
439 | /** The component used to render the sidebar */
440 | const Sidebar = ({ className, children, ...props }: Element<"div">) => {
441 | const ref = React.useRef();
442 |
443 | useLayoutEffect(() => {
444 | if (!ref.current) {
445 | return;
446 | }
447 |
448 | const page = document.querySelector("html");
449 | const sideBarPosition = Number(
450 | localStorage.getItem(sidebarScrollPositionKey)
451 | );
452 |
453 | requestAnimationFrame(() => {
454 | if (sideBarPosition) {
455 | ref.current.scrollTop = sideBarPosition;
456 | }
457 | });
458 |
459 | localStorage.setItem(sidebarScrollPositionKey, "0");
460 | }, []);
461 |
462 | return (
463 |
482 | );
483 | };
484 |
485 | /** The component used to render a divider in the sidebar */
486 | const SidebarDivider = ({ className, ...props }: Element<"hr">) => (
487 |
495 | );
496 |
497 | /** The component used to render a title in the sidebar */
498 | const SidebarTitle = ({ className, ...props }: Element<"p">) => (
499 |
508 | );
509 |
510 | /** The component used to render around a link in the sidebar */
511 | const SidebarItemWrapper = ({ className, ...props }: Element<"li">) => (
512 |
513 | );
514 |
515 | /** The component used to render around a list of sidebar items */
516 | const SidebarList = (props: Element<"ul">) => ;
517 |
518 | interface SidebarLinkProps {
519 | /** Whether the link is the current active page */
520 | isActive?: boolean;
521 | }
522 |
523 | /** The component used to render around a link in a sidebar item */
524 | const SidebarLink = React.forwardRef(
525 | (
526 | { isActive, className, onClick, ...props }: Element<"a"> & SidebarLinkProps,
527 | ref: React.Ref
528 | ) => (
529 | {
540 | localStorage.setItem(
541 | sidebarScrollPositionKey,
542 | String(document.querySelector(".sidebar-items").scrollTop)
543 | );
544 | onClick(e);
545 | }}
546 | />
547 | )
548 | );
549 |
550 | const DEFAULT_SPACING = "my-4";
551 | const DEFAULT_TEXT_COLOR = "text-gray-800 dark:text-gray-300";
552 | const HEADER_TEXT_COLOR = "text-gray-900 dark:text-gray-200";
553 |
554 | /** The component used to render a h1 */
555 | const h1 = ({ className, ...props }: Element<"h1">) => {
556 | return (
557 |
567 | );
568 | };
569 |
570 | /** The component used to render a h2 */
571 | const h2 = ({ className, ...props }: Element<"h2">) => (
572 |
584 | );
585 |
586 | /** The component used to render a h3 */
587 | const h3 = ({ className, ...props }: Element<"h3">) => (
588 |
598 | );
599 |
600 | /** The component used to render a h4 */
601 | const h4 = ({ className, ...props }: Element<"h4">) => (
602 |
611 | );
612 |
613 | /** The component used to render a h5 */
614 | const h5 = ({ className, ...props }: Element<"h5">) => (
615 |
624 | );
625 |
626 | /** The component used to render a h6 */
627 | const h6 = ({ className, ...props }: Element<"h6">) => (
628 |
637 | );
638 |
639 | /** The component used to render a p */
640 | const p = ({ className, ...props }: Element<"p">) => (
641 |
645 | );
646 |
647 | /** The component used to render a li */
648 | const li = ({ className, ...props }: Element<"li">) => (
649 |
653 | );
654 |
655 | /** The component used to render a blockquote */
656 | const blockquote = ({ className, ...props }: Element<"blockquote">) => (
657 |
665 | );
666 |
667 | /** The component used to render a `code` in a line of text */
668 | const inlineCode = ({ className, ...props }: Element<"code">) => (
669 |
678 | );
679 |
680 | /** The component used to render an anchor */
681 | const a = React.forwardRef(
682 | (
683 | { className = "", href, ...props }: Element<"a">,
684 | ref: React.Ref
685 | ) => {
686 | if (href.startsWith("http")) {
687 | return (
688 |
698 | );
699 | }
700 |
701 | return (
702 |
703 |
713 |
714 | );
715 | }
716 | );
717 |
718 | /** The component used to render an ul */
719 | const ul = ({ className, ...props }: Element<"ul">) => (
720 |
721 | );
722 |
723 | const hr = ({ className, ...props }: Element<"hr">) => (
724 |
728 | );
729 |
730 | /** The component used to render an ol */
731 | const ol = ({ className, ...props }: Element<"ol">) => (
732 |
733 | );
734 |
735 | /** The component used to render an block of code */
736 | const code = ({ className, ...props }: Element<"code">) => (
737 |
745 | );
746 |
747 | /** The component used to render a pre */
748 | const pre = ({ className, ...props }: Element<"pre">) => (
749 |
761 | );
762 |
763 | const table = ({ className, ...props }: Element<"table">) => (
764 |
770 | );
771 |
772 | const th = ({ className, ...props }: Element<"th">) => (
773 |
777 | );
778 |
779 | const td = ({ className, ...props }: Element<"td">) => (
780 |
788 | );
789 |
790 | const tr = ({ className, ...props }: Element<"tr">) => (
791 |
792 | );
793 |
794 | const img = ({ className, src, ...props }: Element<"img">) => (
795 |
796 | );
797 |
798 | const components = {
799 | Logo,
800 | NavBarWrapper,
801 | NavBar,
802 | NavBarItem,
803 | SearchInput,
804 | MobileMenuButton,
805 |
806 | Sidebar,
807 | SidebarItemWrapper,
808 | SidebarLink,
809 | SidebarTitle,
810 | SidebarDivider,
811 | SidebarList,
812 |
813 | h1,
814 | h2,
815 | h3,
816 | h4,
817 | h5,
818 | h6,
819 | hr,
820 | p,
821 | inlineCode,
822 | code,
823 | pre,
824 | a,
825 | ul,
826 | ol,
827 | li,
828 | blockquote,
829 | img,
830 |
831 | table,
832 | th,
833 | tr,
834 | td,
835 | } as const;
836 |
837 | export type Components = MDXProviderComponents & typeof components;
838 |
839 | export default components;
840 |
--------------------------------------------------------------------------------
/src/components/navbar.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import { titleCase } from "title-case";
4 | import { useMDXComponents } from "@mdx-js/react";
5 | import makeClass from "clsx";
6 |
7 | import { MobileMenuContext } from "../utils/mobile-menu-context";
8 | import { Components, Element } from "./mdx-components";
9 | import { postFixHTML } from "../utils/format-path";
10 |
11 | const GitHubIcon = ({ className, ...props }: Element<"svg">) => (
12 |
18 |
19 |
20 | );
21 |
22 | /** Renders the search bar and results */
23 | const Search = () => {
24 | const { SearchInput } = useMDXComponents() as Components;
25 |
26 | return (
27 |
28 |
29 |
30 | );
31 | };
32 |
33 | interface NavBarProps {
34 | /** The names of the top level sections */
35 | sections: string[];
36 | /** Whether the site has a home page */
37 | hasHomePage?: boolean;
38 | }
39 |
40 | /** Renders the top level sections of the website */
41 | export const NavBar = ({ sections, hasHomePage }: NavBarProps) => {
42 | const [openMenu, setOpenMenu] = React.useContext(MobileMenuContext);
43 | const {
44 | Logo,
45 | NavBarWrapper,
46 | NavBar,
47 | NavBarItem,
48 | MobileMenuButton,
49 | } = useMDXComponents() as Components;
50 |
51 | return (
52 | <>
53 |
54 |
55 | {hasHomePage ? (
56 |
57 |
58 |
59 | ) : (
60 |
61 | )}
62 |
63 |
64 |
65 |
66 |
71 |
72 |
73 | {sections.map((section) => (
74 |
75 | {titleCase(section)}
76 |
77 | ))}
78 |
79 | {process.env.REPO_URL && (
80 |
85 |
86 |
87 | )}
88 |
89 |
90 |
91 |
92 |
93 | {openMenu && (
94 |
95 | {sections.map((section) => (
96 |
97 | {titleCase(section)}
98 |
99 | ))}
100 | {process.env.REPO_URL && (
101 |
102 |
103 | Open on GitHub
104 |
105 | )}
106 |
107 | )}
108 | >
109 | );
110 | };
111 |
--------------------------------------------------------------------------------
/src/components/open-graph-tags.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useRouter } from "next/router";
3 | import join from "url-join";
4 |
5 | import { Page } from "../utils/types";
6 | import Head from "next/head";
7 |
8 | export const OpenGraphTags = ({
9 | title,
10 | description,
11 | image,
12 | }: Pick) => {
13 | const router = useRouter();
14 | const url = process.env.DOCS_URL
15 | ? join(process.env.DOCS_URL, router.pathname)
16 | : undefined;
17 |
18 | return (
19 |
20 | {/* */}
21 | {title}
22 | {description && }
23 |
24 | {/* */}
25 |
26 |
27 |
28 | {description && }
29 | {image && }
30 |
31 | {/* */}
32 | {url && (
33 |
34 | )}
35 |
36 |
37 | {description && }
38 | {image && }
39 |
40 | );
41 | };
42 |
--------------------------------------------------------------------------------
/src/components/sidebar.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import Head from "next/head";
4 | import path from "path";
5 | import makeClass from "clsx";
6 | import { MDXProvider, useMDXComponents } from "@mdx-js/react";
7 | import { useRouter } from "next/router";
8 |
9 | import { MobileMenuContext } from "../utils/mobile-menu-context";
10 | import { formatPath, postFixHTML } from "../utils/format-path";
11 | import { Page } from "../utils/types";
12 | import { Components } from "./mdx-components";
13 |
14 | export const SidebarActiveItem = React.createContext({
15 | pathname: "",
16 | sidebarFileLocation: "",
17 | });
18 |
19 |
20 | /** Get the custom sidebar for a folder */
21 | const getCustomSidebar = (sidebarFileLocation: string) => {
22 | try {
23 | return require(process.env.PAGES_DIR + sidebarFileLocation + "/_sidebar.mdx").default;
24 | } catch (error) {
25 | try {
26 | return require(process.env.PAGES_DIR + sidebarFileLocation + "/_sidebar.js").default;
27 | } catch (error) {
28 | // TODO handle more file types
29 | }
30 | }
31 | };
32 |
33 | const useActive = (links: Page[]) => {
34 | const router = useRouter();
35 | // We are resolving against the __resourcePath which will
36 | // be relative from the base `docs` folder
37 | const urlPath =
38 | process.env.NEXT_PHASE === "phase-production-build" ||
39 | !router.pathname.includes(process.env.BASE_PATH)
40 | ? path.relative("/", router.pathname)
41 | : path.relative(process.env.BASE_PATH, router.pathname);
42 |
43 | let newActive = links.find((link) => {
44 | const route = link.__resourcePath.replace(".mdx", "");
45 | return route === urlPath;
46 | });
47 |
48 | if (!newActive) {
49 | newActive = links.find((link) => {
50 | const route = link.__resourcePath.replace(".mdx", "");
51 |
52 | return (
53 | route.endsWith("index") &&
54 | router.pathname.includes(route.replace("/index", ""))
55 | );
56 | });
57 | }
58 |
59 | return {
60 | title: newActive.title || process.env.PROJECT_NAME,
61 | pathname: formatPath(newActive.__resourcePath),
62 | };
63 | };
64 |
65 | interface SidebarItemProps {
66 | /** Where the item links to */
67 | href: string;
68 | /** The text of the item */
69 | children: React.ReactNode;
70 | }
71 |
72 | /** An link to a page in the sidebar */
73 | const SidebarItem = ({ href, children }: SidebarItemProps) => {
74 | const active = React.useContext(SidebarActiveItem);
75 | const { SidebarLink } = useMDXComponents() as Components;
76 | const urlPath = path.join(active.sidebarFileLocation, href);
77 |
78 | let url = href;
79 |
80 | if (active.sidebarFileLocation) {
81 | url = urlPath;
82 |
83 | if (url.endsWith("/index")) {
84 | url = url.replace("/index", "");
85 | }
86 |
87 | if (url.endsWith("/")) {
88 | url = url.slice(0, -1);
89 | }
90 | }
91 |
92 | return (
93 |
94 |
97 | {children}
98 |
99 |
100 | );
101 | };
102 |
103 | interface SidebarProps {
104 | /** Pages the sidebar links to */
105 | links: Page[];
106 | /** The folder/top-level section to render */
107 | folder: string;
108 | }
109 |
110 | /** The sidebar with link to all the pages */
111 | export const Sidebar = ({ links, folder }: SidebarProps) => {
112 | const [menuOpen] = React.useContext(MobileMenuContext);
113 | const sidebarFileLocation = `/${folder}`;
114 | const CustomSideBar = getCustomSidebar(sidebarFileLocation);
115 | const active = useActive(links);
116 |
117 | const {
118 | SidebarItemWrapper,
119 | SidebarLink,
120 | SidebarTitle,
121 | SidebarDivider,
122 | SidebarList,
123 | Sidebar,
124 | ...components
125 | } = useMDXComponents() as Components;
126 |
127 | return (
128 |
134 |
144 |
145 | {active.title.replace(/\\`/g, "`")}
146 |
147 |
148 | {CustomSideBar ? (
149 |
150 | ) : (
151 |
152 | {links.map((page) => (
153 |
154 |
155 | {page.title}
156 |
157 |
158 | ))}
159 |
160 | )}
161 |
162 |
163 |
164 | );
165 | };
166 |
--------------------------------------------------------------------------------
/src/css/tailwind.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss/base";
2 | @import "tailwindcss/components";
3 | @import "tailwindcss/utilities";
4 |
5 | /* purgecss start ignore */
6 | @import "@reach/skip-nav/styles";
7 | /* purgecss end ignore */
8 |
9 | #ignite {
10 | .search-results {
11 | max-height: calc(100vh - 64px);
12 | }
13 |
14 | @screen lg {
15 | .search-results {
16 | max-height: 80vh;
17 | }
18 | }
19 |
20 | .small-blog-card:hover .content-fade {
21 | @apply from-gray-100 dark:from-gray-900;
22 | }
23 |
24 | .big-blog-card:hover .content-fade {
25 | @apply from-gray-900 via-gray-700 to-gray-600;
26 | }
27 |
28 | .blog-description {
29 | margin: 0;
30 | }
31 |
32 | .big-blog-card .blog-description,
33 | .big-blog-card .blog-description *:not(code) {
34 | color: theme("colors.gray.100") !important;
35 | }
36 |
37 | .blockquote > *:first-child {
38 | @apply mt-0;
39 | }
40 |
41 | .blockquote > *:last-child {
42 | @apply mb-0;
43 | }
44 |
45 | .ul li {
46 | @apply list-disc ml-6;
47 | }
48 |
49 | .ol li {
50 | @apply list-decimal ml-6;
51 | }
52 |
53 | tbody .tr:nth-child(odd) {
54 | @apply bg-gray-100;
55 | }
56 |
57 | .sidebar-root ul ul {
58 | padding-left: 10px;
59 | }
60 |
61 | .sidebar-root ul + p {
62 | @apply mt-8;
63 | }
64 |
65 | @screen lg {
66 | .sidebar-items {
67 | height: calc(100vh - 4rem);
68 | }
69 | }
70 |
71 | .lvl1 code {
72 | font-size: calc(theme("fontSize.3xl") * 0.93);
73 | }
74 |
75 | @screen lg {
76 | .lvl1 code {
77 | font-size: calc(theme("fontSize.4xl") * 0.93);
78 | }
79 | }
80 |
81 | .lvl2 code {
82 | font-size: calc(theme("fontSize.2xl") * 0.93);
83 | }
84 |
85 | @screen lg {
86 | .lvl2 code {
87 | font-size: calc(theme("fontSize.3xl") * 0.93);
88 | }
89 | }
90 |
91 | .lvl3 code {
92 | font-size: calc(theme("fontSize.xl") * 0.93);
93 | }
94 |
95 | @screen lg {
96 | .lvl3 code {
97 | font-size: calc(theme("fontSize.2xl") * 0.93);
98 | }
99 | }
100 |
101 | .lvl4 code {
102 | font-size: calc(1theme ("fontSize.xl") * 0.93);
103 | }
104 |
105 | .lvl5 code {
106 | font-size: calc(theme("fontSize.lg") * 0.93);
107 | }
108 |
109 | .lvl6 code {
110 | font-size: calc(theme("fontSize.base") * 0.93);
111 | }
112 |
113 | p > code {
114 | font-size: 0.9rem;
115 | }
116 |
117 | h1 > code {
118 | font-size: 2rem;
119 | }
120 |
121 | table code {
122 | @apply whitespace-nowrap;
123 | }
124 |
125 | .search-result:hover .search-content {
126 | @apply bg-gray-100;
127 | }
128 |
129 | h1,
130 | h2,
131 | h3,
132 | h4,
133 | h5,
134 | h6 {
135 | scroll-margin-top: 6rem;
136 | }
137 | }
138 |
139 | @media (prefers-color-scheme: dark) {
140 | #ignite {
141 | @apply text-gray-400;
142 |
143 | tbody .tr:nth-child(odd) {
144 | @apply bg-gray-900;
145 | }
146 |
147 | .search-result:hover .search-content {
148 | @apply bg-gray-800;
149 | }
150 | }
151 | }
152 |
153 | .syntax-dark {
154 | display: none;
155 | }
156 |
157 | @media (prefers-color-scheme: dark) {
158 | .syntax-light {
159 | display: none;
160 | }
161 |
162 | .syntax-dark {
163 | display: block;
164 | }
165 | }
166 |
167 | html {
168 | @apply dark:bg-gray-1000;
169 | }
170 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as BlogLayout } from "./layouts/blog";
2 | export { default as DocsLayout } from "./layouts/docs";
3 | export { default as HomePageLayout } from "./layouts/home-page";
4 | export { default as NavBarLayout } from "./layouts/nav-bar";
5 |
6 | export { default as igniteComponents } from "./components/mdx-components";
7 | export * from "./components/mdx-components";
8 | export * from "./components/open-graph-tags";
9 | export { default as BlogIndex } from "./components/blog-index";
10 | export * from "./utils/format-path";
11 | export * from "./utils/is-dark-mode";
12 |
--------------------------------------------------------------------------------
/src/layouts/blog.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import makeClass from "clsx";
3 | import Head from "next/head";
4 | import { SkipNavContent } from "@reach/skip-nav";
5 |
6 | import NavBarLayout from "./nav-bar";
7 | import { BlogPost } from "../utils/types";
8 | import Avatar from "../components/avatar";
9 | import { OpenGraphTags } from "../components/open-graph-tags";
10 |
11 | const dateFormat = new Intl.DateTimeFormat("en-us", {
12 | year: "numeric",
13 | month: "short",
14 | day: "numeric",
15 | });
16 |
17 | interface BlogPageFrontMatter extends BlogPost {
18 | /** Theme color for the home page */
19 | color?: string;
20 | /** Image to use instead of the color */
21 | image?: string;
22 | }
23 |
24 | /** A layout to render a basic home page */
25 | const BlogLayout = ({
26 | children: content,
27 | frontMatter,
28 | }: React.PropsWithChildren<{ frontMatter: BlogPageFrontMatter }>) => {
29 | const color = frontMatter.color || "primary";
30 |
31 | return (
32 | <>
33 |
34 |
35 |
36 | {frontMatter.title.replace(/\\`/g, "`")}
37 |
38 |
39 |
40 |
41 | {frontMatter.image ? (
42 |
50 | ) : (
51 |
52 | )}
53 |
54 |
62 |
63 |
64 |
70 | {frontMatter.title}
71 |
72 |
73 | {frontMatter.author} {" "}
74 |
78 | on {dateFormat.format(new Date(frontMatter.date))}
79 |
80 |
81 |
82 | {content}
83 |
84 |
85 |
89 |
90 | >
91 | );
92 | };
93 |
94 | export default BlogLayout;
95 |
--------------------------------------------------------------------------------
/src/layouts/docs.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import path from "path";
3 | import { useMDXComponents, MDXProviderComponents } from "@mdx-js/react";
4 | import makeClass from "clsx";
5 | import { SkipNavContent } from "@reach/skip-nav";
6 |
7 | import { Sidebar } from "../components/sidebar";
8 | import NavBarLayout from "./nav-bar";
9 | import { Page } from "../utils/types";
10 | import getFrontMatters from "../utils/get-front-matters";
11 | import { OpenGraphTags } from "../components/open-graph-tags";
12 |
13 | const CODE_BLOCK_REGEX = /([^`]*)`([^`]*)`(.*)/m;
14 |
15 | function constructTitleFromMarkdown(
16 | components: MDXProviderComponents,
17 | str: string
18 | ) {
19 | if (!str) {
20 | return;
21 | }
22 |
23 | const children = [];
24 | let rest = str.replace(/\\`/g, "`");
25 |
26 | while (CODE_BLOCK_REGEX.test(rest)) {
27 | const [, before, inCodeBlock, after] = rest.match(CODE_BLOCK_REGEX);
28 |
29 | children.push(before);
30 | children.push({inCodeBlock} );
31 | rest = after;
32 | }
33 |
34 | children.push(rest);
35 |
36 | return {children}
;
37 | }
38 |
39 | const DocsLayout = ({
40 | children: content,
41 | frontMatter,
42 | }: React.PropsWithChildren<{ frontMatter: Page }>) => {
43 | const [menuOpen, setMenuOpen] = React.useState(false);
44 | const components = useMDXComponents();
45 | const resource = frontMatter.__resourcePath.split("/")[0];
46 | // Find pages that match the current route
47 | const frontMatters = getFrontMatters();
48 | const links = (JSON.parse(process.env.PAGES) as string[])
49 | .map((key) => path.relative("./", key))
50 | .filter((key) => key.startsWith(resource))
51 | .map((key) => frontMatters.find((f) => f.__resourcePath === key));
52 |
53 | return (
54 | <>
55 |
56 |
57 |
58 |
59 |
60 |
61 |
70 | {frontMatter.title && (
71 |
72 | {constructTitleFromMarkdown(components, frontMatter.title)}
73 |
74 | )}
75 | {content}
76 |
77 |
78 |
79 | >
80 | );
81 | };
82 |
83 | export default DocsLayout;
84 |
--------------------------------------------------------------------------------
/src/layouts/home-page.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import makeClass from "clsx";
4 | import Head from "next/head";
5 | import { SkipNavContent } from "@reach/skip-nav";
6 |
7 | import NavBarLayout from "./nav-bar";
8 | import { Page } from "../utils/types";
9 | import { postFixHTML } from "../utils/format-path";
10 | import { OpenGraphTags } from "../components/open-graph-tags";
11 |
12 | interface HomePageFrontMatter extends Page {
13 | /** Theme color for the home page */
14 | color: string;
15 | /** Tagline for the homepage */
16 | tagline: string;
17 | /** CTA for the homepage */
18 | cta: string;
19 | }
20 |
21 | /** A layout to render a basic home page */
22 | const HomePageLayout = ({
23 | children: content,
24 | frontMatter,
25 | }: React.PropsWithChildren<{ frontMatter: HomePageFrontMatter }>) => {
26 | const color = frontMatter.color || "primary";
27 | const title = frontMatter.title || process.env.PROJECT_NAME;
28 |
29 | return (
30 |
31 |
32 | {process.env.PROJECT_NAME}
33 |
34 |
35 |
40 |
41 |
42 |
70 |
76 | {content}
77 |
78 |
79 | );
80 | };
81 |
82 | export default HomePageLayout;
83 |
--------------------------------------------------------------------------------
/src/layouts/nav-bar.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Head from "next/head";
3 | import { SkipNavLink } from "@reach/skip-nav";
4 |
5 | import { NavBar } from "../components/navbar";
6 | import { MobileMenuContext } from "../utils/mobile-menu-context";
7 | import { formatPath } from "../utils/format-path";
8 | import { useDarkMode } from "../utils/is-dark-mode";
9 |
10 | interface NavBarProps {
11 | /** The state of the mobile menu */
12 | menuState?: [boolean, (newValue: boolean) => void];
13 | /** The page content */
14 | children: React.ReactNode;
15 | }
16 |
17 | /** Make a basic navbar page layout */
18 | const NavBarLayout = ({
19 | children: content,
20 | ...props
21 | }: NavBarProps & React.PropsWithChildren<{}>) => {
22 | const menuState = React.useState(false);
23 |
24 | React.useEffect(() => {
25 | if (typeof document === "undefined") {
26 | return;
27 | }
28 |
29 | function focusSearch(e: KeyboardEvent) {
30 | if (e.key === "/") {
31 | document.getElementById("search").focus();
32 | e.preventDefault();
33 | }
34 | }
35 |
36 | document.addEventListener("keydown", focusSearch);
37 |
38 | return () => {
39 | document.removeEventListener("keydown", focusSearch);
40 | };
41 | }, []);
42 |
43 | const isDark = useDarkMode();
44 |
45 | return (
46 |
47 |
48 |
55 |
56 |
57 |
58 |
59 |
60 |
64 | {content}
65 |
66 |
67 | );
68 | };
69 |
70 | export default NavBarLayout;
71 |
--------------------------------------------------------------------------------
/src/layouts/none.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | /** just render the mdx content */
4 | const NavBarLayout = ({ children }: React.PropsWithChildren<{}>) => {
5 | return children;
6 | };
7 |
8 | export default NavBarLayout;
9 |
--------------------------------------------------------------------------------
/src/next.ts:
--------------------------------------------------------------------------------
1 | import { IShikiTheme } from "shiki";
2 | import fs from "fs";
3 | import path from "path";
4 |
5 | import { execSync } from "child_process";
6 | import autoLink from "rehype-autolink-headings";
7 | import a11yEmoji from "rehype-accessible-emojis";
8 | import shiki from "rehype-shiki-reloaded";
9 | import slug from "rehype-slug";
10 | import emoji from "remark-emoji";
11 | import withPWA from "next-pwa";
12 |
13 | import { getEnv } from "./utils/get-env";
14 | import { IgniteConfig } from "./utils/types";
15 | import { getAuthor } from "./utils/get-author";
16 | import { DOCS_DIR } from "./utils/docs-data";
17 | import mdxEnhanced from "next-mdx-enhanced";
18 | import { createAdditionalManifestAssets } from "./utils/create-additional-manifest-asset";
19 |
20 | const cachingStrategy = require("next-pwa/cache");
21 | const withBundleAnalyzer = require("@next/bundle-analyzer")({
22 | enabled: process.env.ANALYZE === "true",
23 | });
24 |
25 | const getCreationDate = (file: string) => {
26 | try {
27 | return execSync(
28 | `git log --diff-filter=A --follow --format=%aD -- ${path.join(
29 | "docs/pages",
30 | file
31 | )} | tail -1`,
32 | {
33 | encoding: "utf8",
34 | stdio: ["pipe", "ignore", "ignore"],
35 | }
36 | );
37 | } catch (error) {
38 | return "";
39 | }
40 | };
41 |
42 | const resolveTheme = (theme: string | IShikiTheme, defaultTheme: string) => {
43 | return theme
44 | ? typeof theme === "string" && fs.existsSync(theme)
45 | ? path.resolve(theme)
46 | : theme
47 | : defaultTheme;
48 | };
49 |
50 | // ignite config options
51 | // url - the url your site is deployed to
52 | // name - The name of the project you are documenting
53 | // repo - The repo the documentation is for
54 | // order - string array of top level section order
55 | // htmlUrls - Add .html to the end of each URL
56 | export default (igniteConfig: IgniteConfig = {}) => (nextConfig = {}) => {
57 | const debug = process.env.NODE_ENV !== "production";
58 | const env = getEnv(igniteConfig);
59 | const basePath = debug
60 | ? ""
61 | : env.BASE_PATH !== "/"
62 | ? env.BASE_PATH
63 | : undefined;
64 |
65 | process.env = {
66 | ...process.env,
67 | ...env,
68 | };
69 |
70 | const withMdxEnhanced = mdxEnhanced({
71 | layoutPath: path.resolve(path.join(__dirname, "./layouts")),
72 | remarkPlugins: [emoji, ...(igniteConfig.remarkPlugins || [])],
73 | rehypePlugins: [
74 | slug,
75 | [
76 | autoLink,
77 | {
78 | behavior: "wrap",
79 | properties: {
80 | className:
81 | 'header-link no-underline text-gray-900" hover:underline',
82 | },
83 | },
84 | ],
85 | a11yEmoji,
86 | [
87 | shiki,
88 | {
89 | theme: resolveTheme(igniteConfig.lightSyntaxTheme, "github-light"),
90 | darkTheme: resolveTheme(igniteConfig.darkSyntaxTheme, "github-dark"),
91 | langs: [
92 | {
93 | id: "mdx",
94 | scopeName: "text.html.markdown.jsx",
95 | path: path.join(__dirname, "./utils/mdx-lang.json"),
96 | },
97 | ],
98 | },
99 | ],
100 | ...(igniteConfig.rehypePlugins || []),
101 | ],
102 | extendFrontMatter: {
103 | process: (mdx: string, frontMatter) => {
104 | let {
105 | __resourcePath,
106 | date,
107 | layout,
108 | description,
109 | ...rest
110 | } = frontMatter;
111 | const creationDate = getCreationDate(__resourcePath);
112 | const [author, email] = getAuthor(__resourcePath);
113 |
114 | if (!layout) {
115 | const defaultLayout = __resourcePath.split("/")[0];
116 |
117 | if (__resourcePath === "index.mdx") {
118 | layout = "home-page";
119 | } else if (__resourcePath.includes("_sidebar.mdx")) {
120 | return {};
121 | } else if (
122 | fs.existsSync(path.join(__dirname, `layouts/${defaultLayout}.js`))
123 | ) {
124 | layout = defaultLayout;
125 | } else {
126 | layout = "docs";
127 | }
128 | }
129 |
130 | if (!description && layout === "blog") {
131 | const [, firstParagraph] =
132 | mdx.match(/---\n\n^([^#].+?)(?=^$)/ms) ||
133 | mdx.match(/\n\n^([^#].+?)(?=^$)/ms) ||
134 | [];
135 |
136 | if (firstParagraph) {
137 | description = firstParagraph;
138 | }
139 | }
140 |
141 | return {
142 | layout,
143 | description,
144 | date: date || creationDate,
145 | author: rest.author || author,
146 | email: rest.email || email,
147 | };
148 | },
149 | phase: "both",
150 | },
151 | });
152 |
153 | const config = withBundleAnalyzer(
154 | withMdxEnhanced({
155 | ...nextConfig,
156 | basePath,
157 | publicRuntimeConfig: {
158 | assetPrefix: basePath,
159 | },
160 | env: {
161 | ...env,
162 | browser: "true",
163 | },
164 | })
165 | );
166 |
167 | config.ignite = igniteConfig;
168 |
169 | if (env.BUILD_PWA === "true") {
170 | cachingStrategy[0] = {
171 | ...cachingStrategy[0],
172 | urlPattern: env.BASE_PATH,
173 | };
174 |
175 | return withPWA({
176 | ...config,
177 | pwa: {
178 | disable: process.env.NODE_ENV !== "production",
179 | subdomainPrefix: env.BASE_PATH,
180 | runtimeCaching: cachingStrategy,
181 | additionalManifestEntries: [
182 | ...createAdditionalManifestAssets(
183 | path.join(DOCS_DIR, "public", "**/*"),
184 | env.BASE_PATH
185 | ),
186 | { url: "replace-me", revision: "replace-me" },
187 | ],
188 | },
189 | });
190 | }
191 |
192 | return config;
193 | };
194 |
--------------------------------------------------------------------------------
/src/utils/build-rss-feed.ts:
--------------------------------------------------------------------------------
1 | import { Feed } from "feed";
2 | import { IgniteConfig } from "./types";
3 | import join from "url-join";
4 | import fs from "fs";
5 | import cheerio from "cheerio";
6 | import path from "path";
7 | import glob from "fast-glob";
8 |
9 | import { Resource, BlogPost } from "./types";
10 | import { getEnv } from "./get-env";
11 | import { getAuthor } from "./get-author";
12 | import { DOCS_DIR, MDX_DATA_DIR } from "./docs-data";
13 |
14 | export const buildRssFeed = (config: IgniteConfig) => {
15 | const env = getEnv(config);
16 | const posts = glob
17 | .sync(path.join(MDX_DATA_DIR, '**/*'))
18 | .map((p) => JSON.parse(fs.readFileSync(p, "utf-8")) as Resource)
19 | .filter((page) => page.__resourcePath.startsWith("blog")) as BlogPost[];
20 |
21 | if (!posts.length) {
22 | return;
23 | }
24 |
25 | const author = getAuthor();
26 | const feed = new Feed({
27 | title: config.name,
28 | description: `The ${config.name} blog feed.`,
29 | id: config.url,
30 | link: config.url,
31 | language: "en",
32 | favicon: join(config.url, "favicon.ico"),
33 | image: env.PROJECT_LOGO.startsWith("http")
34 | ? env.PROJECT_LOGO
35 | : join(config.url, env.PROJECT_LOGO),
36 | feedLinks: {
37 | json: join(config.url, "blog", "json"),
38 | atom: join(config.url, "blog", "atom"),
39 | },
40 | copyright: `All rights reserved ${new Date().getFullYear()}, ${author[0]}`,
41 | author: {
42 | name: author[0],
43 | email: author[1],
44 | },
45 | });
46 |
47 | posts.map((post) => {
48 | const author = [];
49 |
50 | if (post.author && post.email) {
51 | author.push({ name: post.author, email: post.email });
52 | } else {
53 | const fileAuthor = getAuthor(post.__resourcePath);
54 | author.push({ name: fileAuthor[0], email: fileAuthor[1] });
55 | }
56 |
57 | const html = fs.readFileSync(
58 | path.join(DOCS_DIR, "out", post.__resourcePath.replace(".mdx", ".html")),
59 | "utf-8"
60 | );
61 | const $ = cheerio.load(html);
62 | const content = $("article").html();
63 |
64 | feed.addItem({
65 | title: post.title,
66 | date: new Date(post.date),
67 | id: join(config.url, post.__resourcePath.replace(".mdx", "")),
68 | link: join(config.url, post.__resourcePath.replace(".mdx", "")),
69 | author: author,
70 | contributor: author,
71 | image: post.image,
72 | content,
73 | });
74 | });
75 |
76 | fs.writeFileSync(path.join(DOCS_DIR, 'out/blog', 'feed.xml'), feed.rss2())
77 | };
78 |
--------------------------------------------------------------------------------
/src/utils/build-search-index.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import { relative, join } from "path";
3 | import * as cheerio from "cheerio";
4 | import { Element, NodeWithChildren } from "domhandler";
5 |
6 | import glob from "fast-glob";
7 | import { DOCS_DIR } from "./docs-data";
8 |
9 | const getContentBeforeNextHeading = (
10 | $: ReturnType,
11 | node: NodeWithChildren
12 | ) => {
13 | const next = $(node).nextAll().toArray();
14 | let content = "";
15 |
16 | for (let index = 0; index < next.length; index++) {
17 | const element = next[index];
18 |
19 | if ($(element).attr('class')?.includes('lvl')) {
20 | break;
21 | }
22 |
23 | content += `\n${$(element).text()}`;
24 | }
25 |
26 | return content;
27 | };
28 |
29 | const getHeadingsBeforeNextHeading = (
30 | $: ReturnType,
31 | node: NodeWithChildren,
32 | lvl: number
33 | ) => {
34 | const next = $(node).nextAll().toArray();
35 | const titles = [];
36 |
37 | for (let index = 0; index < next.length; index++) {
38 | const element = next[index];
39 | const $el = $(element)
40 |
41 | if ($el.hasClass(`lvl${lvl}`)) {
42 | break;
43 | }
44 |
45 | if ($el.hasClass(`lvl${lvl + 1}`)) {
46 | titles.push(element);
47 | }
48 | }
49 |
50 | return titles;
51 | };
52 |
53 | const getPage = (page: string) => {
54 | const content = fs.readFileSync(page, "utf-8");
55 | const $ = cheerio.load(content);
56 |
57 | const lvl0Node = $(".lvl0")
58 | .toArray()
59 | .find((title) => $(".sidebar-active", $(title.next)).length);
60 | const isBlog = page.includes("/blog/");
61 | const lvl0 = isBlog ? "Blog" : $(lvl0Node).text();
62 |
63 | const buildTree = (parents: string[], node: Element, lvl = 1) => {
64 | const searchNode = isBlog && lvl === 1 ? node.parent : node;
65 | const nextHeadings = getHeadingsBeforeNextHeading($, searchNode, lvl);
66 | const path = [...parents, $(node).text()];
67 |
68 | const currentNode = {
69 | path,
70 | url: `${relative(DOCS_DIR, page)
71 | .replace("out/", "")
72 | .replace(".html", "")}${node.attribs.id ? `#${node.attribs.id}` : ""}`,
73 | content: getContentBeforeNextHeading($, searchNode),
74 | };
75 |
76 | return [
77 | currentNode,
78 | ...nextHeadings.reduce(
79 | (acc, heading) => [...acc, ...buildTree(path, heading, lvl + 1)],
80 | []
81 | ),
82 | ];
83 | };
84 |
85 | const firstLvl = [1, 2, 3, 4, 5, 6]
86 | .map((lvl) => $(`.lvl${lvl}`)[0])
87 | .find(Boolean);
88 |
89 | if (!firstLvl) {
90 | return;
91 | }
92 |
93 | return buildTree([lvl0], firstLvl);
94 | };
95 |
96 | export const buildSearchIndex = (dest = "out") => {
97 | return glob(join(DOCS_DIR, "out/**/*.html")).then((pages) => {
98 | const pagesToIndex = pages.filter(
99 | (page) =>
100 | !page.includes("/_sidebar") &&
101 | !page.includes("out/blog.html") &&
102 | !page.includes("out/404.html") &&
103 | !page.includes("out/index.html")
104 | );
105 |
106 | fs.writeFileSync(
107 | join(DOCS_DIR, dest, "search-index.json"),
108 | JSON.stringify(pagesToIndex.map(getPage).flat().filter(Boolean), null, 2)
109 | );
110 | });
111 | };
112 |
--------------------------------------------------------------------------------
/src/utils/create-additional-manifest-asset.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import path from "path";
3 | import crypto from "crypto";
4 | import glob from "fast-glob";
5 |
6 | import { DOCS_DIR, OUT_DIR } from "./docs-data";
7 |
8 | const getRevision = (file: string) =>
9 | crypto.createHash("md5").update(fs.readFileSync(file)).digest("hex");
10 |
11 | export const createAdditionalManifestAssets = (
12 | pattern: string,
13 | basePath: string
14 | ) => {
15 | return glob.sync(pattern).map((f) => ({
16 | url: path.posix.join(
17 | basePath,
18 | f.includes("/public/")
19 | ? path.relative(path.join(DOCS_DIR, "public"), f)
20 | : path.relative(OUT_DIR, f)
21 | ),
22 | revision: getRevision(f),
23 | }));
24 | };
25 |
--------------------------------------------------------------------------------
/src/utils/docs-data.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import path from "path";
3 | import glob from "fast-glob";
4 |
5 | export const DOCS_DIR = path.resolve("./docs");
6 | export const OUT_DIR = path.join(DOCS_DIR, "out");
7 | export const PAGES_DIR = path.resolve("./docs/pages");
8 | export const MDX_DATA_DIR = path.resolve("./docs/.mdx-data");
9 |
10 | export const getPages = () => glob.sync(path.join(PAGES_DIR, "/**/*.mdx"));
11 | export const getBlogPosts = () =>
12 | glob.sync(path.join(PAGES_DIR, "blog", "/**/*.mdx"));
13 | export const getHasHomepage = () =>
14 | Boolean(glob.sync(path.join(PAGES_DIR, "index.+(mdx|js|jsx|ts|tsx)")).length);
15 |
16 | export const getTopLevelSections = (order = ["docs", "blog"]) => {
17 | const requirePage = getPages();
18 |
19 | return Array.from(
20 | new Set(
21 | requirePage
22 | .map((key) => path.relative(PAGES_DIR, key))
23 | // anything with a dot in it would be a file
24 | // we only care about directories
25 | .filter((key) => key.includes("/"))
26 | .map((key) => key.split("/")[0])
27 | .sort((a, b) => {
28 | if (!order.includes(a) && !order.includes(b)) {
29 | return a.localeCompare(b);
30 | }
31 |
32 | if (!order.includes(a)) {
33 | return 1;
34 | }
35 |
36 | if (!order.includes(b)) {
37 | return -1;
38 | }
39 |
40 | return order.indexOf(a) - order.indexOf(b);
41 | })
42 | )
43 | );
44 | };
45 |
46 | export const getFrontMatters = () => {
47 | const frontMatters = glob.sync(path.join(MDX_DATA_DIR, "*.json"));
48 |
49 | return frontMatters.map((m) => {
50 | const data = JSON.parse(fs.readFileSync(m, "utf-8"));
51 |
52 | return {
53 | __resourcePath: data.__resourcePath,
54 | date: data.date,
55 | title: data.title,
56 | author: data.author,
57 | email: data.email,
58 | };
59 | });
60 | };
61 |
--------------------------------------------------------------------------------
/src/utils/format-path.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 |
3 | export function formatPath(p: string) {
4 | return path.join(process.env.BASE_PATH, `/${p.replace(/\.mdx$/, "")}`);
5 | }
6 |
7 | export function postFixHTML(p: string) {
8 | if (!process.env.STATIC_HTML_URLS) {
9 | return p
10 | }
11 |
12 | if (p.startsWith("#")) {
13 | return p;
14 | }
15 |
16 | // Handle: path/to/page#header
17 | if (path.basename(p).includes('#')) {
18 | return p.replace('#', '.html#')
19 | }
20 |
21 | return `${p}.html`;
22 | }
23 |
--------------------------------------------------------------------------------
/src/utils/generate-pwa-assets.ts:
--------------------------------------------------------------------------------
1 | import * as pwaAssetGenerator from "pwa-asset-generator";
2 | import path from "path";
3 | import cheerio from "cheerio";
4 | import glob from "fast-glob";
5 | import fs from "fs";
6 |
7 | import { DOCS_DIR, OUT_DIR } from "./docs-data";
8 | import { getEnv } from "./get-env";
9 | import { IgniteConfig } from "./types";
10 | import { formatPath } from "./format-path";
11 | import { createAdditionalManifestAssets } from "./create-additional-manifest-asset";
12 |
13 | export const generatePwaAssets = async (config: IgniteConfig) => {
14 | const env = getEnv(config);
15 | const manifestPath = path.join(OUT_DIR, "manifest.json");
16 | const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
17 |
18 | const light = await pwaAssetGenerator.generateImages(
19 | path.join(DOCS_DIR, "public", env.PROJECT_LOGO),
20 | OUT_DIR,
21 | {
22 | pathOverride: env.BASE_PATH,
23 | log: false,
24 | background: manifest.background_color,
25 | }
26 | );
27 |
28 | const dark = await pwaAssetGenerator.generateImages(
29 | path.join(DOCS_DIR, "public", env.PROJECT_LOGO_DARK),
30 | OUT_DIR,
31 | {
32 | darkMode: true,
33 | pathOverride: env.BASE_PATH,
34 | log: false,
35 | background: manifest.dark_background_color,
36 | }
37 | );
38 |
39 | // Add items to manifest
40 | manifest.icons = [...light.manifestJsonContent, ...dark.manifestJsonContent];
41 | manifest.start_url = path.join(env.BASE_PATH, "/");
42 |
43 | fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
44 |
45 | // Add to html HEADs
46 | const html = await glob(path.join(OUT_DIR, "**/*.html"));
47 |
48 | html.map((file) => {
49 | const $ = cheerio.load(fs.readFileSync(file, "utf-8"));
50 |
51 | $("head").append(
52 | [...Object.values(light.htmlMeta), ...Object.values(dark.htmlMeta)]
53 | .map((image) => {
54 | if (image.includes("apple-icon-180.jpg")) {
55 | return image.replace("apple-icon-180.jpg", "apple-icon-180.png");
56 | }
57 |
58 | return image;
59 | })
60 | .join("\n")
61 | );
62 | $("head").append(`
63 |
64 |
65 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | `);
80 | fs.writeFileSync(file, $.html());
81 | });
82 |
83 | const additionalAssets = createAdditionalManifestAssets(
84 | path.join(OUT_DIR, "**/*.html"),
85 | env.BASE_PATH
86 | );
87 |
88 | if (additionalAssets.length) {
89 | const swFilename = path.join(OUT_DIR, "sw.js");
90 | const sw = fs.readFileSync(swFilename, "utf-8");
91 | fs.writeFileSync(
92 | swFilename,
93 | sw.replace(
94 | '{url:"replace-me",revision:"replace-me"}',
95 | additionalAssets.map((a) => JSON.stringify(a)).join(",")
96 | )
97 | );
98 | }
99 | };
100 |
--------------------------------------------------------------------------------
/src/utils/get-author.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import { execSync } from "child_process";
3 | import { PAGES_DIR } from "./docs-data";
4 |
5 | type User = [name: string, email: string];
6 |
7 | export const getAuthor = (file?: string): User => {
8 | try {
9 | const target = file ? path.join(PAGES_DIR, file) : "HEAD";
10 |
11 | return execSync(`git log --format="%an || %ae" ${target} | tail -1`, {
12 | encoding: "utf8",
13 | stdio: ["pipe", "ignore", "ignore"],
14 | }).split(" || ") as User;
15 | } catch (error) {
16 | return ["", ""];
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/src/utils/get-blog-posts.ts:
--------------------------------------------------------------------------------
1 | import getFrontMatters from "./get-front-matters";
2 | import { BlogPost } from "./types";
3 |
4 | /** Get all the blog posts in the project */
5 | const getBlogPosts = () => {
6 | try {
7 | const frontMatters = getFrontMatters();
8 |
9 | return (JSON.parse(process.env.BLOG_POSTS) as string[])
10 | .map((key) => frontMatters.find((f) => f.__resourcePath === key))
11 | .filter((post): post is BlogPost => Boolean(post))
12 | .map((post) => ({
13 | ...post,
14 | __resourcePath: post.__resourcePath.replace(/\.mdx$/, ""),
15 | }))
16 | .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
17 | } catch (error) {
18 | return [];
19 | }
20 | };
21 |
22 | export default getBlogPosts;
23 |
--------------------------------------------------------------------------------
/src/utils/get-config.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import { cosmiconfigSync } from "cosmiconfig";
3 | import { IgniteConfig } from "./types";
4 |
5 | const explorer = cosmiconfigSync("ignite");
6 |
7 | export const getConfig = (): IgniteConfig => {
8 | const { config = {} } = explorer.search() || {};
9 |
10 | if (!config.name) {
11 | try {
12 | const packageJSON = require(path.join(process.cwd(), "package.json"));
13 | config.name = packageJSON.name;
14 | } catch (error) {}
15 | }
16 |
17 | return config;
18 | };
19 |
--------------------------------------------------------------------------------
/src/utils/get-env.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import glob from "fast-glob";
3 | import parseGithubUrl from "parse-github-url";
4 |
5 | import {
6 | getTopLevelSections,
7 | getHasHomepage,
8 | getPages,
9 | getBlogPosts,
10 | PAGES_DIR,
11 | MDX_DATA_DIR,
12 | } from "./docs-data";
13 | import { IgniteConfig } from "./types";
14 |
15 | const publicDir = "./docs/public/";
16 | const DEFAULT_LOGO = "https://hipstersmoothie.github.io/next-ignite/logo.svg";
17 |
18 | const getFullGitHubUrl = (url: string) => {
19 | const repo = parseGithubUrl(url);
20 |
21 | if (!repo) {
22 | return "https://hipstersmoothie.github.io/next-ignite/docs/configuration#repo";
23 | }
24 |
25 | if (repo.href.startsWith("http")) {
26 | return repo.href;
27 | }
28 |
29 | return `https://github.com/${repo.repo}`;
30 | };
31 |
32 | export const getEnv = (config: IgniteConfig) => {
33 | const debug = process.env.NODE_ENV !== "production";
34 | const { pathname } = config.url ? new URL(config.url) : { pathname: "/" };
35 | const BASE_PATH = debug
36 | ? ""
37 | : pathname.endsWith("/")
38 | ? pathname.slice(0, -1)
39 | : pathname;
40 | const manifest = glob.sync(path.join(publicDir, "**/manifest.json"))[0];
41 | const favicon = glob.sync(path.join(publicDir, "**/favicon.*"))[0];
42 | const faviconDark = glob.sync(path.join(publicDir, "**/favicon-dark.*"))[0];
43 | const logo = glob.sync(path.join(publicDir, "**/logo.*"))[0];
44 | const darkLogo = glob.sync(path.join(publicDir, "**/logo-dark.*"))[0];
45 | const PROJECT_LOGO = logo ? path.relative(publicDir, logo) : DEFAULT_LOGO;
46 |
47 | return {
48 | BUILD_PWA: String(Boolean(manifest)),
49 | BASE_PATH: debug ? "/" : BASE_PATH || "/",
50 | STATIC_HTML_URLS: debug
51 | ? ""
52 | : config.htmlUrls === true
53 | ? "true" || undefined
54 | : "",
55 | PROJECT_NAME: config.name,
56 | FAVICON: favicon ? path.relative(publicDir, favicon) : "",
57 | FAVICON_DARK: faviconDark ? path.relative(publicDir, faviconDark) : "",
58 | PROJECT_LOGO,
59 | PROJECT_LOGO_DARK: darkLogo
60 | ? path.relative(publicDir, darkLogo)
61 | : PROJECT_LOGO || DEFAULT_LOGO,
62 | REPO_URL: getFullGitHubUrl(config.repo),
63 | PAGES_DIR,
64 | MDX_DATA_DIR,
65 | DOCS_URL: config.url,
66 | HAS_HOMEPAGE: getHasHomepage() ? "true" : undefined,
67 | TOP_LEVEL_SECTIONS: JSON.stringify(getTopLevelSections(config.order)),
68 | BLOG_POSTS: JSON.stringify(
69 | getBlogPosts().map((p) => path.relative(PAGES_DIR, p))
70 | ),
71 | PAGES: JSON.stringify(getPages().map((p) => path.relative(PAGES_DIR, p))),
72 | };
73 | };
74 |
--------------------------------------------------------------------------------
/src/utils/get-front-matters.ts:
--------------------------------------------------------------------------------
1 | import { BlogPost, MarkdownPage } from "./types";
2 |
3 | let frontMatters: (MarkdownPage | BlogPost)[] = [];
4 |
5 | try {
6 | const context = require.context(process.env.MDX_DATA_DIR, true, /\.json$/);
7 | frontMatters = context.keys().map(context) as (MarkdownPage | BlogPost)[];
8 | } catch (error) {
9 | if (!process.env.browser) {
10 | // When ran from server use node to get frontMatters
11 | try {
12 | const path = require("path");
13 | const fs = require("fs");
14 | const glob = require("fast-glob");
15 |
16 | const files = glob.sync(path.join(process.env.MDX_DATA_DIR, "*.json"));
17 |
18 | frontMatters = files.map((file) =>
19 | JSON.parse(fs.readFileSync(file, "utf-8"))
20 | ) as (MarkdownPage | BlogPost)[];
21 | } catch (error) {}
22 | }
23 | }
24 |
25 | /** Get all the blog posts in the project */
26 | const getFrontMatters = () => {
27 | try {
28 | return frontMatters;
29 | } catch (error) {
30 | return [];
31 | }
32 | };
33 |
34 | export default getFrontMatters;
35 |
--------------------------------------------------------------------------------
/src/utils/is-dark-mode.ts:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import usePassiveLayoutEffect from "@react-hook/passive-layout-effect";
3 |
4 | export function isDarkMode() {
5 | if (
6 | window.matchMedia &&
7 | window.matchMedia("(prefers-color-scheme: dark)").matches
8 | ) {
9 | return true;
10 | }
11 |
12 | return false;
13 | }
14 |
15 | export function useDarkMode() {
16 | const [isDark, isDarkSet] = React.useState(false);
17 |
18 | usePassiveLayoutEffect(() => {
19 | const darkModeMediaQuery = window.matchMedia(
20 | "(prefers-color-scheme: dark)"
21 | );
22 | const updateDark = () => {
23 | isDarkSet(window.matchMedia("(prefers-color-scheme: dark)").matches);
24 | };
25 |
26 | updateDark();
27 | darkModeMediaQuery.addListener(updateDark);
28 |
29 | return () => {
30 | darkModeMediaQuery.removeListener(updateDark);
31 | };
32 | }, []);
33 |
34 | return isDark;
35 | }
36 |
--------------------------------------------------------------------------------
/src/utils/mdx-lang.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3 | "name": "mdx",
4 | "patterns": [
5 | {
6 | "include": "#jsx"
7 | },
8 | {
9 | "include": "#markdown"
10 | }
11 | ],
12 | "repository": {
13 | "jsx": {
14 | "patterns": [
15 | {
16 | "include": "#jsx-module"
17 | },
18 | {
19 | "include": "#jsx-tag"
20 | }
21 | ],
22 | "repository": {
23 | "jsx-module": {
24 | "patterns": [
25 | {
26 | "begin": "^(?=(import|export)\\b)",
27 | "while": "^(?!\\s*$)",
28 | "contentName": "source.js.jsx",
29 | "patterns": [
30 | {
31 | "include": "source.js.jsx"
32 | }
33 | ]
34 | }
35 | ]
36 | },
37 | "jsx-tag": {
38 | "patterns": [
39 | {
40 | "begin": "^(?=<([a-z]|[A-Z]))",
41 | "end": "(?<=>)",
42 | "contentName": "source.js.jsx",
43 | "patterns": [
44 | {
45 | "include": "source.js.jsx"
46 | }
47 | ]
48 | }
49 | ]
50 | }
51 | }
52 | },
53 | "markdown": {
54 | "contentName": "text.html.markdown",
55 | "patterns": [
56 | {
57 | "include": "text.html.markdown"
58 | }
59 | ]
60 | }
61 | },
62 | "scopeName": "text.html.markdown.jsx"
63 | }
--------------------------------------------------------------------------------
/src/utils/mobile-menu-context.ts:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export const MobileMenuContext = React.createContext<
4 | [boolean, (newOpenValue: boolean) => void]
5 | >([false, () => {}]);
6 |
--------------------------------------------------------------------------------
/src/utils/purge-unused-css.ts:
--------------------------------------------------------------------------------
1 | import PurgeCSS from "purgecss";
2 | import glob from "fast-glob";
3 | import path from "path";
4 | import fs from "fs";
5 | import prettyBytes from "pretty-bytes";
6 |
7 | import { IgniteConfig } from "./types";
8 | import { DOCS_DIR } from "./docs-data";
9 |
10 | function tailwindExtractor(content: string) {
11 | // Capture as liberally as possible, including things like `h-(screen-1.5)`
12 | const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];
13 | const broadMatchesWithoutTrailingSlash = broadMatches.map((match) =>
14 | match.replace(/\\$/, "")
15 | );
16 |
17 | // Capture classes within other delimiters like .block(class="w-1/2") in Pug
18 | const innerMatches =
19 | content.match(/[^<>"'`\s.(){}[\]#=%]*[^<>"'`\s.(){}[\]#=%:]/g) || [];
20 |
21 | return broadMatches
22 | .concat(broadMatchesWithoutTrailingSlash)
23 | .concat(innerMatches);
24 | }
25 |
26 | const logBytes = (str: string) => prettyBytes(Buffer.byteLength(str, "utf8"));
27 |
28 | export const purgeUnusedCss = async (config: IgniteConfig) => {
29 | if (config.purge !== false) {
30 | const results = await new PurgeCSS().purge({
31 | // Scan the out dir for any className usage
32 | content: glob.sync(path.join(DOCS_DIR, "out/**/*"), {
33 | // Exclude all css from usage gathering
34 | ignore: ["**/*.css"],
35 | }),
36 | // Purge the output css
37 | css: glob.sync(path.join(DOCS_DIR, "out/_next/static/css/**/*.css")),
38 | defaultExtractor: (content) => [...tailwindExtractor(content)],
39 | });
40 |
41 | if (!results.length) {
42 | return;
43 | }
44 |
45 | console.log("PurgeCSS Results:");
46 |
47 | results.map((result) => {
48 | if (result.file) {
49 | const before = fs.readFileSync(result.file, "utf-8");
50 |
51 | console.log(
52 | `${result.file}: ${logBytes(before)} => ${logBytes(result.css)}`
53 | );
54 | fs.writeFileSync(result.file, result.css);
55 | }
56 | });
57 | }
58 | };
59 |
--------------------------------------------------------------------------------
/src/utils/sitemap.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import sitemap from "nextjs-sitemap-generator";
3 | import { getConfig } from "./get-config";
4 |
5 | const config = getConfig();
6 | const buildDir = path.join(process.cwd(), "docs/out");
7 |
8 | export const buildSitemap = () =>
9 | sitemap({
10 | baseUrl:
11 | config.url && config.url.endsWith("/")
12 | ? config.url.slice(0, -1)
13 | : config.url,
14 | pagesDirectory: buildDir,
15 | targetDirectory: buildDir,
16 | ignoreIndexFiles: true,
17 | ignoredPaths: ["404"],
18 | ignoredExtensions: ["png", "jpg", "svg", "ico", "js", "xml", "json"],
19 | });
20 |
--------------------------------------------------------------------------------
/src/utils/types.ts:
--------------------------------------------------------------------------------
1 | import * as shiki from "shiki";
2 |
3 | export interface Resource {
4 | /** Path to file */
5 | __resourcePath: string;
6 | date: string;
7 | }
8 |
9 | export interface Page extends Resource {
10 | /** Title from front-matter */
11 | title: string;
12 | /** The description for the page, used in meta tags */
13 | description?: string;
14 | image?: string;
15 | }
16 |
17 | export interface BlogPost extends Page {
18 | author: string;
19 | email?: string;
20 | }
21 |
22 | export interface MarkdownPage extends Page {
23 | author: string;
24 | email?: string;
25 | content: string;
26 | }
27 |
28 | export interface IgniteConfig {
29 | /** The name to use for the docs */
30 | name?: string;
31 | /** The repo the docs are for */
32 | repo?: string;
33 | /** The url the docs will be deployed to */
34 | url?: string;
35 | /** Produce links with .html URLs */
36 | htmlUrls?: boolean;
37 | /** The order of the nav items */
38 | order?: string[];
39 | /** Whether to purge unused CSS from static build */
40 | purge?: boolean;
41 | /** The light theme to use for syntax highlighting */
42 | lightSyntaxTheme?: string | shiki.IShikiTheme;
43 | /** The dark theme to use for syntax highlighting */
44 | darkSyntaxTheme?: string | shiki.IShikiTheme;
45 | /** Plugins for remark. JS CONFIG ONLY */
46 | remarkPlugins?: any[];
47 | /** Plugins for rehype. JS CONFIG ONLY */
48 | rehypePlugins?: any[];
49 | }
50 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | const { colors } = require("tailwindcss/defaultTheme");
2 |
3 | module.exports = {
4 | darkMode: "media",
5 | purge: false,
6 | theme: {
7 | extend: {
8 | colors: {
9 | primary: {
10 | 100: `var(--color-primary-100, ${colors.blue["100"]})`,
11 | 200: `var(--color-primary-200, ${colors.blue["200"]})`,
12 | 300: `var(--color-primary-300, ${colors.blue["300"]})`,
13 | 400: `var(--color-primary-400, ${colors.blue["400"]})`,
14 | 500: `var(--color-primary-500, ${colors.blue["500"]})`,
15 | 600: `var(--color-primary-600, ${colors.blue["600"]})`,
16 | 700: `var(--color-primary-700, ${colors.blue["700"]})`,
17 | 800: `var(--color-primary-800, ${colors.blue["800"]})`,
18 | 900: `var(--color-primary-900, ${colors.blue["900"]})`,
19 | },
20 |
21 | gray: {
22 | 100: `var(--color-gray-100, ${colors.gray["100"]})`,
23 | 200: `var(--color-gray-200, ${colors.gray["200"]})`,
24 | 300: `var(--color-gray-300, ${colors.gray["300"]})`,
25 | 400: `var(--color-gray-400, ${colors.gray["400"]})`,
26 | 500: `var(--color-gray-500, ${colors.gray["500"]})`,
27 | 600: `var(--color-gray-600, ${colors.gray["600"]})`,
28 | 700: `var(--color-gray-700, ${colors.gray["700"]})`,
29 | 800: `var(--color-gray-800, ${colors.gray["800"]})`,
30 | 900: `var(--color-gray-900, ${colors.gray["900"]})`,
31 | 1000: `var(--color-gray-1000, #11151d)`,
32 | },
33 | },
34 | },
35 | },
36 | variants: {
37 | extend: {
38 | ringWidth: ["focus-visible"],
39 | },
40 | },
41 | };
42 |
--------------------------------------------------------------------------------
/template/pages/__app.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { AppProps } from "next/app";
3 | import { MDXProvider } from "@mdx-js/react";
4 | import { igniteComponents } from "next-ignite";
5 |
6 | import "next-ignite/dist/main.css";
7 |
8 | function MyApp({ Component, pageProps }: AppProps) {
9 | return (
10 |
11 |
12 |
13 | );
14 | }
15 |
16 | export default MyApp;
17 |
--------------------------------------------------------------------------------
/template/pages/docs/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Welcome"
3 | ---
4 |
5 | Welcome to `ignite`! :tada:
6 |
--------------------------------------------------------------------------------
/template/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hipstersmoothie/next-ignite/d3859d57f1669951c56d48109811bd36b4258d89/template/public/favicon.ico
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*"],
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "outDir": "dist",
6 | "declaration": true,
7 | "emitDeclarationOnly": true,
8 | "esModuleInterop": true,
9 | "lib": ["DOM", "es2019"]
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/typings/next-prefixed.d.ts:
--------------------------------------------------------------------------------
1 | declare module "next-prefixed" {
2 | export function prefixURL(url: string): string;
3 | }
4 |
--------------------------------------------------------------------------------