Skip to content

Commit

Permalink
Merge pull request #80 from chrisweb/preview
Browse files Browse the repository at this point in the history
Next.js 15 migration + next.js 15 static first mdx tutorial
  • Loading branch information
chrisweb authored Jan 1, 2025
2 parents 0238cd9 + 9aa8e79 commit e480e10
Show file tree
Hide file tree
Showing 208 changed files with 21,855 additions and 6,373 deletions.
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true

[*.{md,mdx}]
indent_size = 2
insert_final_newline = true

[*.{js,jsx,mjs,ts,tsx,mts,json}]
indent_size = 4
108 changes: 0 additions & 108 deletions .eslintrc.js

This file was deleted.

74 changes: 44 additions & 30 deletions .no-dead-urls.remarkrc.mjs
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
import remarkLintNoDeadUrls from 'remark-lint-no-dead-urls'

/** @type {import('remark-lint-no-dead-urls').Options} */
const remarkLintNoDeadUrlsOptions = {
from: 'http://localhost:3000',
skipUrlPatterns: [
// can't find the anchor element for the hash
// document is very big and loads slowly
// might be due to a timeout
'/*w3c.github.io*/',
// pexels blocks all requests with a 403 (forbidden) response
'/*pexels.com*/',
// github urls with a hash for the line numbers
// produce the error that the hash can not be found as anchor element
// I do NOT want to disable all of github.com
// disabling all the urls with a line number hash would be ideal but not sure how to do that
// for now I search for /blob/ or /blame/ in the URL and exclude those
'/*/blob/*/',
'/*/blame/*/',
// this page wants to redirect to a url with the language set
// I prefer to use the URL with no language
// so that it adapts to the user's language that will visit
'/*azure.microsoft.com*/',
// npmjs has low rate limit, often returns 429 (too many requests)
'/*npmjs.com*/',
// these domains often produce fetch errors
'/*https://developer.apple.com/*/',
'/*archive.org*/',
// images have /public in their path
// next.js however uses a cached version /_next/image?url=
// for now I exclude them all, future we need something to convert URLs
'/*/public/assets/images*/',
// discord always returns 403 (forbidden)
'/*discord.com*/',
],
deadOrAliveOptions: {
// I will wait 60 seconds for the request to complete
timeout: 60000,
// I will retry 1 times
retries: 1,
// I will wait 60 seconds between retries
retryDelay: 60000,
},
}

const config = {
plugins: [
//[remarkLintNoDeadUrls, { from: 'https://example.com' }]
[remarkLintNoDeadUrls, {
from: 'http://localhost:3000',
skipUrlPatterns: [
// can't find the anchor element for the hash
// document is very big and loads slowly
// might be due to a timeout
'/*w3c.github.io*/',
// pexels blocks all requests with a 403 (forbidden) response
'/*pexels.com*/',
// github urls with a hash for the line numbers
// produce the error that the hash can not be found as anchor element
// I do NOT want to disable all of github.com
// disabling all the urls with a line number hash would be ideal but not sure how to do that
// for now I search for /blob/ in the URL and exclude those
'/*/blob/*/',
// this page wants to redirect to a url with the language set
// I prefer to use the URL with no language
// so that it adapts to the user's language that will visit
'/*azure.microsoft.com*/',
// npmjs has low rate limit, often returns 429 (too many requests)
'/*npmjs.com*/',
// these domains often produce fetch errors
'/*https://developer.apple.com/*/',
'/*archive.org*/',
// images have /public in their path
// next.js however uses a cached version /_next/image?url=
// for now I eclude them all, future we need something to convert URLs
'/*/public/assets/images*/',
]
}]
[remarkLintNoDeadUrls, remarkLintNoDeadUrlsOptions]
]
}

Expand Down
14 changes: 10 additions & 4 deletions .remarkrc.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// presets imports
import remarkPresetLintRecommended from 'remark-preset-lint-consistent'
import remarkPresetLintConsistent from 'remark-preset-lint-recommended'
import remarkPresetLintRecommended from 'remark-preset-lint-recommended'
import remarkPresetLintConsistent from 'remark-preset-lint-consistent'
import remarkPresetLintMarkdownStyleGuide from 'remark-preset-lint-markdown-style-guide'

// rules imports
Expand All @@ -10,15 +10,21 @@ import remarkLintNoUndefinedReferences from 'remark-lint-no-undefined-references
import remarkLintLinkTitleStyle from 'remark-lint-link-title-style'
import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length'
import remarkLintListItemSpacing from 'remark-lint-list-item-spacing'

// remark plugins
import remarkGfm from 'remark-gfm'
import remarkFrontmatter from 'remark-frontmatter'

const config = {
plugins: [
// presets
// first the plugins
remarkGfm,
remarkFrontmatter,
// then the presets
remarkPresetLintRecommended,
remarkPresetLintConsistent,
remarkPresetLintMarkdownStyleGuide,
// rules
// and finally the rules customizations
// https://www.npmjs.com/package/remark-lint-maximum-heading-length
[remarkLintMaximumHeadingLength, [1, 100]],
// https://www.npmjs.com/package/remark-lint-unordered-list-marker-style
Expand Down
9 changes: 1 addition & 8 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@
},
"eslint.debug": true,
"eslint.options": {
"extensions": [
".js",
".jsx",
".md",
".mdx",
".ts",
".tsx"
]
"flags": ["unstable_ts_config"]
},
"eslint.validate": [
"markdown",
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@ On [chris.lu](https://chris.lu), you will find my tutorials and can learn more a

## Technologies used

During the development of the blog, I wrote a ["Next.js static MDX blog" tutorial](https://chris.lu/web_development/tutorials/next-js-static-mdx-blog) that showcases most of the technologies that I used
During the development of the blog, I wrote a ["Next.js static MDX blog" tutorial](https://chris.lu/web-development/tutorials/next-js-static-mdx-blog) that showcases most of the technologies that I used

The framework I used is [Next.js 14](https://github.com/vercel/next.js) with [React 18](https://github.com/facebook/react) (I plan on upgrading to Next.js 15 and React 19 as soon as the first stable versions get released and will update my tutorial accordingly)
The framework I used is [Next.js 15.x](https://github.com/vercel/next.js) with [React 19.x](https://github.com/facebook/react)

I added [MDX](https://mdxjs.com/) support to be able to create content using next/mdx. I then also used several remark and rehype plugins and even built two myself, [rehype-github-alerts
](https://github.com/chrisweb/rehype-github-alerts) and [remark-table-of-contents
](https://github.com/chrisweb/remark-table-of-contents)
I added [MDX](https://mdxjs.com/) support to be able to create content using **@next/mdx**. I then also used several MDX (remark and rehype) plugins and even built two myself, [rehype-github-alerts](https://github.com/chrisweb/rehype-github-alerts) and [remark-table-of-contents](https://github.com/chrisweb/remark-table-of-contents)

I had a lot of fun doing my [WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) header animation using [react-three-fiber](https://github.com/pmndrs/react-three-fiber) (a React renderer for [three.js](https://github.com/mrdoob/three.js))

I also added a jukebox on top using my [web-audio-api-player](https://github.com/chrisweb/web-audio-api-player) and added a dynamic waveform using my [waveform-visualizer](https://github.com/chrisweb/waveform-visualizer) and [waveform-data-generator](https://github.com/chrisweb/waveform-data-generator) packages
I also added a jukebox like music player (on the top right) using my [web-audio-api-player](https://github.com/chrisweb/web-audio-api-player) and added a dynamic waveform using my [waveform-visualizer](https://github.com/chrisweb/waveform-visualizer) and [waveform-data-generator](https://github.com/chrisweb/waveform-data-generator) packages

## Feedback & bug reports

Expand All @@ -47,7 +45,11 @@ If you have feedback or want to discuss something, please use the [chris.lu gith
`npm run lint-debug`: linting command but more verbose output
`npm run lint-fix`: linting command that also attempts to automatically fix problems
`npm run info`: the default next.js script to get some info about the project
`npm run check-urls`: check if URLs in documents are alive or not, this linting is seperate from the main linting script so that it can be used sporadically, as it makes lots of calls to 3rd party URLs to check if they are alive, it does not run during the build process so that a unreachable URL of a third party won't break the build
`npm run check-urls`: check if URLs in documents are alive or not, this linting is separate from the main linting script so that it can be used sporadically, as it makes lots of calls to 3rd party URLs to check if they are alive, it does not run during the build process so that a unreachable URL of a third party won't break the build, it is separate from eslint process and uses remark-cli

## Node.js version

Next.js [requires >=18.18.0](https://github.com/vercel/next.js/commit/ecd2be6d3b74d7af2513a8b355408a8f88ec6b25) (same as ESLint v9), Typescript ESLint [requires Node.js >=20.11.0](https://typescript-eslint.io/getting-started/typed-linting) (for import.meta.dirname in ESM files), this projects [package.json](./package.json) has the engines node set to 20.11.0, the latest Node.js LTS is 22.11.0 (Nov. 2024)

## License

Expand Down
38 changes: 13 additions & 25 deletions app/about_me/opengraph-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,16 @@ const title = 'About me'

export const alt = `Chris.lu ${title} banner`

/*interface IImageProps {
params: {
slug: string
}
id: number
}*/

// Image generation
export default async function OGImage(/*props: IImageProps*/) {

//console.log(props)
export default async function Image() {

// Font
const permanentMarkerRegular = fetch(
new URL('/public/assets/fonts/PermanentMarker-Regular.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
).then(res => res.arrayBuffer())

const imageData = await fetch(
new URL('/public/assets/images/og_image_background_1200x630.jpg', import.meta.url)
).then((res) => res.arrayBuffer())
).then(res => res.arrayBuffer())

return new ImageResponse(
// ImageResponse JSX element
Expand All @@ -48,17 +38,15 @@ export default async function OGImage(/*props: IImageProps*/) {
justifyContent: 'center',
}}
>
{
// eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element
<img
// @ts-ignore: this is fine 🔥
src={imageData}
style={{
objectFit: 'cover',
objectPosition: 'center',
}}
/>
}
{/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */}
<img
// @ts-ignore: this is fine 🔥
src={imageData}
style={{
objectFit: 'cover',
objectPosition: 'center',
}}
/>
<span
style={{
position: 'absolute',
Expand Down Expand Up @@ -97,7 +85,7 @@ export default async function OGImage(/*props: IImageProps*/) {
>
{title}
</span>
</div >
</div>
),
// ImageResponse options
{
Expand Down
Loading

0 comments on commit e480e10

Please sign in to comment.