├── .contentlayer ├── .cache │ └── v0.3.1 │ │ ├── compiled-contentlayer-config-2QRL2QTS.mjs │ │ ├── compiled-contentlayer-config-2QRL2QTS.mjs.map │ │ ├── data-2QRL2QTS.json │ │ ├── data-3E5OXYXD.json │ │ ├── data-C2AEZ45X.json │ │ ├── data-DQZJDV74.json │ │ ├── data-ERORW5AG.json │ │ ├── data-J243MMIC.json │ │ ├── data-NIQMQWJR.json │ │ ├── data-O3ZSMIUL.json │ │ ├── data-PYTGB3J6.json │ │ ├── data-QBW3K2YM.json │ │ ├── data-QPKEQ4YM.json │ │ └── data-TLSCPJ4V.json ├── generated │ ├── Post │ │ ├── _index.json │ │ ├── _index.mjs │ │ ├── nextjs-appdir-blog.mdx.json │ │ └── vercel-aws.mdx.json │ ├── index.d.ts │ ├── index.mjs │ └── types.d.ts └── package.json ├── .eslintrc.json ├── .gitignore ├── .vscode └── settings.json ├── README.md ├── app ├── api │ └── hello │ │ └── route.ts ├── globals.css ├── layout.tsx ├── page.module.css ├── page.tsx └── posts │ ├── [slug] │ └── page.tsx │ └── page.tsx ├── components ├── Footer.tsx ├── Header.tsx └── PostNotFound.tsx ├── contentlayer.config.ts ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── posts ├── nextjs-appdir-blog.mdx └── vercel-aws.mdx ├── public ├── favicon.ico ├── next.svg ├── og-image.png └── vercel.svg ├── tailwind.config.js ├── tsconfig.json └── utils ├── mdxcomponents.tsx └── rehypeoptions.ts /.contentlayer/.cache/v0.3.1/compiled-contentlayer-config-2QRL2QTS.mjs: -------------------------------------------------------------------------------- 1 | // contentlayer.config.ts 2 | import { defineDocumentType, makeSource } from "contentlayer/source-files"; 3 | import rehypePrettyCode from "rehype-pretty-code"; 4 | 5 | // utils/rehypeoptions.ts 6 | var rehypeoptions = { 7 | // Use one of Shiki's packaged themes 8 | theme: "slack-ochin", 9 | // Set to true to keep the background color 10 | keepBackground: false, 11 | onVisitLine(node) { 12 | if (node.children.length === 0) { 13 | node.children = [{ type: "text", value: " " }]; 14 | } 15 | }, 16 | onVisitHighlightedLine(node) { 17 | node.properties.className.push("highlighted"); 18 | }, 19 | onVisitHighlightedWord(node, id) { 20 | node.properties.className = ["word"]; 21 | } 22 | }; 23 | 24 | // contentlayer.config.ts 25 | var Post = defineDocumentType(() => ({ 26 | name: "Post", 27 | filePathPattern: `**/*.mdx`, 28 | contentType: "mdx", 29 | fields: { 30 | title: { 31 | type: "string", 32 | description: "The title of the post", 33 | required: true 34 | }, 35 | description: { 36 | type: "string", 37 | description: "The description of the post", 38 | required: true 39 | }, 40 | date: { 41 | type: "date", 42 | description: "The date of the post", 43 | required: true 44 | }, 45 | author: { 46 | type: "string", 47 | description: "The author of the post", 48 | required: true 49 | } 50 | }, 51 | computedFields: { 52 | url: { 53 | type: "string", 54 | resolve: (doc) => `/posts/${doc._raw.flattenedPath}` 55 | } 56 | } 57 | })); 58 | var contentlayer_config_default = makeSource({ 59 | contentDirPath: "posts", 60 | documentTypes: [Post], 61 | mdx: { 62 | rehypePlugins: [[rehypePrettyCode, rehypeoptions]] 63 | } 64 | }); 65 | export { 66 | contentlayer_config_default as default 67 | }; 68 | //# sourceMappingURL=compiled-contentlayer-config-2QRL2QTS.mjs.map 69 | -------------------------------------------------------------------------------- /.contentlayer/.cache/v0.3.1/compiled-contentlayer-config-2QRL2QTS.mjs.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": ["../../../contentlayer.config.ts", "../../../utils/rehypeoptions.ts"], 4 | "sourcesContent": ["import { defineDocumentType, makeSource } from \"contentlayer/source-files\";\nimport rehypePrettyCode from \"rehype-pretty-code\";\nimport { rehypeoptions } from \"./utils/rehypeoptions\";\n\nconst Post = defineDocumentType(() => ({\n name: \"Post\",\n filePathPattern: `**/*.mdx`,\n contentType: \"mdx\",\n fields: {\n title: {\n type: \"string\",\n description: \"The title of the post\",\n required: true,\n },\n description: {\n type: \"string\",\n description: \"The description of the post\",\n required: true,\n },\n date: {\n type: \"date\",\n description: \"The date of the post\",\n required: true,\n },\n author: {\n type: \"string\",\n description: \"The author of the post\",\n required: true,\n },\n },\n computedFields: {\n url: {\n type: \"string\",\n resolve: (doc) => `/posts/${doc._raw.flattenedPath}`,\n },\n },\n}));\n\nexport default makeSource({\n contentDirPath: \"posts\",\n documentTypes: [Post],\n mdx: {\n rehypePlugins: [[rehypePrettyCode, rehypeoptions]],\n },\n});\n", "export const rehypeoptions = {\n // Use one of Shiki's packaged themes\n theme: \"slack-ochin\",\n // Set to true to keep the background color\n keepBackground: false,\n onVisitLine(node: any) {\n if (node.children.length === 0) {\n node.children = [{ type: \"text\", value: \" \" }];\n }\n },\n onVisitHighlightedLine(node: any) {\n node.properties.className.push(\"highlighted\");\n },\n onVisitHighlightedWord(node: any, id: any) {\n node.properties.className = [\"word\"];\n },\n};\n"], 5 | "mappings": ";AAAA,SAAS,oBAAoB,kBAAkB;AAC/C,OAAO,sBAAsB;;;ACDtB,IAAM,gBAAgB;AAAA;AAAA,EAE3B,OAAO;AAAA;AAAA,EAEP,gBAAgB;AAAA,EAChB,YAAY,MAAW;AACrB,QAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,WAAK,WAAW,CAAC,EAAE,MAAM,QAAQ,OAAO,IAAI,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EACA,uBAAuB,MAAW;AAChC,SAAK,WAAW,UAAU,KAAK,aAAa;AAAA,EAC9C;AAAA,EACA,uBAAuB,MAAW,IAAS;AACzC,SAAK,WAAW,YAAY,CAAC,MAAM;AAAA,EACrC;AACF;;;ADZA,IAAM,OAAO,mBAAmB,OAAO;AAAA,EACrC,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,gBAAgB;AAAA,IACd,KAAK;AAAA,MACH,MAAM;AAAA,MACN,SAAS,CAAC,QAAQ,UAAU,IAAI,KAAK;AAAA,IACvC;AAAA,EACF;AACF,EAAE;AAEF,IAAO,8BAAQ,WAAW;AAAA,EACxB,gBAAgB;AAAA,EAChB,eAAe,CAAC,IAAI;AAAA,EACpB,KAAK;AAAA,IACH,eAAe,CAAC,CAAC,kBAAkB,aAAa,CAAC;AAAA,EACnD;AACF,CAAC;", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /.contentlayer/.cache/v0.3.1/data-3E5OXYXD.json: -------------------------------------------------------------------------------- 1 | { 2 | "cacheItemsMap": { 3 | "vercel-aws.mdx": { 4 | "document": { 5 | "title": "Vercel introducing serverless functions and combining with AWS", 6 | "description": "Vercel is a cloud platform for static sites and Serverless Functions that you can deploy instantly, and scale automatically.", 7 | "date": "2023-04-05T18:30:00.000Z", 8 | "author": "Lee Robinson", 9 | "body": { 10 | "raw": "\nHere is the [demo](https://nextjs-appdir-blog.vercel.app) 👋\n\n### Contents\n\n- Create a Next.js app\n- Create a blog page with [contentlayer](https://contentlayer.dev)\n- Styling the blog\n- Custom components\n- List all posts\n- Highlight codes\n\n\n### Let's get started!\n\nFirst, we need to create a new Next.js app with the new app folder feature:\n\n```bash\nnpx create-next-app@latest --ts --experimental-app\n```\n\nYou can also use `Javascript` instead of `Typescript`. In this tutorial we will use `Typescript`.\n\nThen, you need to install the Contentlayer:\n\n```bash\nnpm i contentlayer next-contentlayer @opentelemetry/api\n```\n\nNow, export the `contentlayer` config in the `next.config.js`:\n\n```js\nconst { withContentlayer } = require('next-contentlayer')\n\nmodule.exports = withContentlayer({\n experimental: { appDir: true },\n})\n```\n\nNow, we need to create a `contentlayer.config.ts` file in the root of the project and add the following code:\n\n```ts\nimport { defineDocumentType, makeSource } from \"contentlayer/source-files\";\n\n\nconst Post = defineDocumentType(() => ({\n name: \"Post\",\n filePathPattern: `**/*.mdx`,\n contentType: \"mdx\",\n fields: {\n title: {\n type: \"string\",\n description: \"The title of the post\",\n required: true,\n },\n description: {\n type: \"string\",\n description: \"The description of the post\",\n required: true,\n },\n },\n computedFields: {\n url: {\n type: \"string\",\n resolve: (doc) => `/posts/${doc._raw.flattenedPath}`,\n },\n },\n}));\n\nexport default makeSource({\n contentDirPath: \"posts\",\n documentTypes: [Post],\n});\n\n```\n\nAbove code is the config for the Contentlayer. It will create a `Post` document type and will generate the `url` field based on the `flattenedPath` field.\n\nYou can add more document types and fields such as `Author` and `Category` and more.\n\nNow, we need to create a `posts` folder in the root of the project and create a `hello-world.mdx` file in it and add the following code:\n\n```mdx\n---\ntitle: How to create Next.js app\ndescription: Learn how to create Next.js app\n---\n\n# Install Next.js\n\n### Fist you need to install Next.js with the following command:\n\nnpm i create-next-app@latest\n```\n\nThen, restart the app with the following command:\n\n```bash\nnpm run dev\n```\n\nNow, you can see new `.contentlayer` folder in the root of the project. This folder contains the generated JSON files, types and more.\n\n![generate contentlayer folder](https://i.postimg.cc/nrdVwTLt/Screenshot-2023-04-05-at-6-13-25-PM.png)\n\nNow, we need to create a `posts` folder in the `app` folder and create a `[slug]` folder in it. and create a `page.tsx` file in `[slug]` folder and add the following code:\n\n\n`app/posts/[slug]/page.tsx`\n\n```tsx\nimport { allPosts } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\n\nexport const generateStaticParams = async () =>\n\n\n allPosts.map((post) => ({ slug: post._raw.flattenedPath }));\n export const generateMetadata = ({ params }:any) => {\n const post = allPosts.find((post:any) => post._raw.flattenedPath === params.slug)\n return { title: post?.title,description: post?.description }\n }\n\nconst PostLayout = ({ params }: { params: { slug: string } }) => {\n const post = allPosts.find(\n (post) => post._raw.flattenedPath === params.slug\n );\n\n let MDXContent;\n\n if (!post) {\n return
404
;\n } else {\n MDXContent = getMDXComponent(post!.body.code);\n }\n\n return (\n
\n

\n {post.title}\n

\n

{post.description}

\n
\n \n
\n
\n );\n};\n\nexport default PostLayout;\n\n```\n\nAbove code is the page for the blog post. It will render the blog post based on the `slug` parameter.\n\nNow, you can see the blog rendered in the `http://localhost:3000/posts/hello-world`:\n\n![blog rendered](https://i.postimg.cc/vHZ5HHC0/Screenshot-2023-04-05-at-6-34-14-PM.png)\n\n## Styling the blog\n\nNow, we need to style the blog using `CSS` or others. In this tutorial, we will use `CSS`:\n\n`globals.css`\n\n```css\npre {\n padding: 15px 20px;\n border-radius: 10px;\n background-color: #f9f8f981;\n overflow: auto;\n font-size: 0.9rem;\n margin: 40px 0;\n}\narticle p {\n font-size: 1rem;\n line-height: 1.8rem;\n margin-top: 20px;\n}\narticle h1 {\n font-size: 2.5rem;\n line-height: 3.5rem;\n margin-top: 60px;\n font-weight: 425;\n}\n\n...\n\n```\n\nNow, you can see the blog styled:\n\n![styled blog](https://i.postimg.cc/0jr5kM57/Screenshot-2023-04-05-at-8-43-24-PM.png)\n\nAlso you can use `TailwindCSS` or others.\n\n## Custom components\n\nCustom components is a great feature of `MDX`. You can create your own components and use them in your blog posts.\n\nFor example, we can create a `CodeSnippet` component:\n\n`app/posts/[slug]/page.tsx`\n\n\n```tsx\nimport { allWritings } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\nimport { Snippet } from \"@geist-ui/core\";\n\n...\n\nconst CodeSnippet = (props: any) => (\n \n);\n\n return (\n
\n

\n {writing.title}\n

\n

{writing.description}

\n
\n \n
\n
\n );\n\nexport default PostLayout;\n```\n\nNow, you can use the `CodeSnippet` component in your blog posts:\n\n```mdx\n---\ntitle: How to create a Next.js app\ndescription: Learn how to create a Next.js app\n---\n\n# Install Next.js\n\n### First, install Next.js using the following command:\n\n\n```\n\nNow, you can see the `CodeSnippet` component in the blog post:\n\n![code snippet](https://i.postimg.cc/MT7756nQ/Screenshot-2023-04-05-at-9-33-21-PM.png)\n\n## List all posts\n\nNow, we need to create a page that lists all posts. For this, we need to create a `posts` folder in the `app` folder and create a `page.tsx` file in it and add the following code:\n\n`app/posts/page.tsx`\n\n```tsx\nimport Link from 'next/link'\nimport { allPosts, Post } from 'contentlayer/generated'\n\nfunction PostCard(post: Post) {\n return (\n
\n

\n \n {post.title}\n \n

\n

{post.description}

\n
\n )\n}\n\nfunction page() {\n const posts = allPosts\n\n return (\n
\n
\n {posts.map((post, idx) => (\n \n ))}\n
\n
\n )\n}\n\nexport default page;\n```\n\nNow, you can see the list of all posts in the `http://localhost:3000/posts`:\n\n![list of all posts](https://i.postimg.cc/LsRQMbjL/Screenshot-2023-04-05-at-10-23-37-PM.png)\n\n## Highlight codes\n\nNow, we need to highlight the codes in the blog posts. For this, we will use `rehype-pretty-code`:\n\n```bash\nnpm i rehype-pretty-code shiki\n```\n\nNow, we need to add the `rehype-pretty-code` plugin to the `contentlayer.config.ts` file:\n\n`contentlayer.config.ts`\n\n```ts\nimport { defineDocumentType, makeSource } from \"contentlayer/source-files\";\nimport rehypePrettyCode from \"rehype-pretty-code\";\n\nconst Writing = defineDocumentType(() => ({\n ...\n}));\n\nconst rehypeoptions = {\n // Use one of Shiki's packaged themes\n theme: \"light-plus\",\n // Set to true to keep the background color\n keepBackground: true ,\n onVisitLine(node: any) {\n if (node.children.length === 0) {\n node.children = [{ type: \"text\", value: \" \" }];\n }\n },\n onVisitHighlightedLine(node: any) {\n node.properties.className.push(\"highlighted\");\n },\n onVisitHighlightedWord(node: any, id: any) {\n node.properties.className = [\"word\"];\n },\n };\n\nexport default makeSource({\n contentDirPath: \"writings\",\n documentTypes: [Writing],\n mdx: {\n rehypePlugins: [[rehypePrettyCode, rehypeoptions]],\n },\n});\n\n```\n\nNow, you can see the highlighted codes in the blog posts:\n\n![highlighted codes](https://i.postimg.cc/mrPYKxrm/Screenshot-2023-04-05-at-10-44-36-PM.png)\n\nYou can find more information about [rehype-pretty-code](https://rehype-pretty-code.netlify.app/)\nand [Shiki themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes).\n\n## Conclusion\n\nIn this tutorial, we have learned how to create a blog using `Next.js`, `Contentlayer`, and `MDX`. We have learned how to create a blog post, how to list all posts, and how to highlight codes in the blog posts.\n\nYou can find the source code of the `Contentlayer` blog in the following GitHub repository:\n\n[Source code of example](https://github.com/contentlayerdev/next-contentlayer-example)\n\n## Resources\n\n- [Contentlayer](https://contentlayer.dev/)\n- [Next.js](https://nextjs.org/)\n- [MDX](https://mdxjs.com/)\n- [rehype-pretty-code](https://rehype-pretty-code.netlify.app/)\n- [Shiki themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes)\n\n## About the author\n\n[Arshad Yaseen](https://arshadd.site). I'm a software engineer and I love to create aesthetic frontends. If you have any questions, feel free to ask me on [Twitter](https://twitter.com/arshadyaseeen).", 11 | "code": "var Component=(()=>{var ln=Object.create;var T=Object.defineProperty;var cn=Object.getOwnPropertyDescriptor;var un=Object.getOwnPropertyNames;var pn=Object.getPrototypeOf,fn=Object.prototype.hasOwnProperty;var B=(c,n)=>()=>(n||c((n={exports:{}}).exports,n),n.exports),mn=(c,n)=>{for(var b in n)T(c,b,{get:n[b],enumerable:!0})},ye=(c,n,b,N)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let x of un(n))!fn.call(c,x)&&x!==b&&T(c,x,{get:()=>n[x],enumerable:!(N=cn(n,x))||N.enumerable});return c};var hn=(c,n,b)=>(b=c!=null?ln(pn(c)):{},ye(n||!c||!c.__esModule?T(b,\"default\",{value:c,enumerable:!0}):b,c)),bn=c=>ye(T({},\"__esModule\",{value:!0}),c);var Pe=B((jn,je)=>{je.exports=React});var ke=B(q=>{\"use strict\";(function(){\"use strict\";var c=Pe(),n=Symbol.for(\"react.element\"),b=Symbol.for(\"react.portal\"),N=Symbol.for(\"react.fragment\"),x=Symbol.for(\"react.strict_mode\"),z=Symbol.for(\"react.profiler\"),G=Symbol.for(\"react.provider\"),K=Symbol.for(\"react.context\"),L=Symbol.for(\"react.forward_ref\"),O=Symbol.for(\"react.suspense\"),F=Symbol.for(\"react.suspense_list\"),U=Symbol.for(\"react.memo\"),A=Symbol.for(\"react.lazy\"),Ue=Symbol.for(\"react.offscreen\"),J=Symbol.iterator,we=\"@@iterator\";function Ee(e){if(e===null||typeof e!=\"object\")return null;var a=J&&e[J]||e[we];return typeof a==\"function\"?a:null}var j=c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function f(e){{for(var a=arguments.length,s=new Array(a>1?a-1:0),t=1;t=1&&p>=0&&i[u]!==m[p];)p--;for(;u>=1&&p>=0;u--,p--)if(i[u]!==m[p]){if(u!==1||p!==1)do if(u--,p--,p<0||i[u]!==m[p]){var h=`\n`+i[u].replace(\" at new \",\" at \");return e.displayName&&h.includes(\"\")&&(h=h.replace(\"\",e.displayName)),typeof e==\"function\"&&E.set(e,h),h}while(u>=1&&p>=0);break}}}finally{Y=!1,M.current=l,Ye(),Error.prepareStackTrace=o}var k=e?e.displayName||e.name:\"\",Ne=k?w(k):\"\";return typeof e==\"function\"&&E.set(e,Ne),Ne}function Ve(e,a,s){return oe(e,!1)}function $e(e){var a=e.prototype;return!!(a&&a.isReactComponent)}function C(e,a,s){if(e==null)return\"\";if(typeof e==\"function\")return oe(e,$e(e));if(typeof e==\"string\")return w(e);switch(e){case O:return w(\"Suspense\");case F:return w(\"SuspenseList\")}if(typeof e==\"object\")switch(e.$$typeof){case L:return Ve(e.render);case U:return C(e.type,a,s);case A:{var t=e,o=t._payload,l=t._init;try{return C(l(o),a,s)}catch{}}}return\"\"}var S=Object.prototype.hasOwnProperty,le={},ce=j.ReactDebugCurrentFrame;function R(e){if(e){var a=e._owner,s=C(e.type,e._source,a?a.type:null);ce.setExtraStackFrame(s)}else ce.setExtraStackFrame(null)}function Xe(e,a,s,t,o){{var l=Function.call.bind(S);for(var d in e)if(l(e,d)){var i=void 0;try{if(typeof e[d]!=\"function\"){var m=Error((t||\"React class\")+\": \"+s+\" type `\"+d+\"` is invalid; it must be a function, usually from the `prop-types` package, but received `\"+typeof e[d]+\"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.\");throw m.name=\"Invariant Violation\",m}i=e[d](a,d,t,s,null,\"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED\")}catch(u){i=u}i&&!(i instanceof Error)&&(R(o),f(\"%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).\",t||\"React class\",s,d,typeof i),R(null)),i instanceof Error&&!(i.message in le)&&(le[i.message]=!0,R(o),f(\"Failed %s type: %s\",s,i.message),R(null))}}}var He=Array.isArray;function W(e){return He(e)}function Be(e){{var a=typeof Symbol==\"function\"&&Symbol.toStringTag,s=a&&e[Symbol.toStringTag]||e.constructor.name||\"Object\";return s}}function qe(e){try{return ue(e),!1}catch{return!0}}function ue(e){return\"\"+e}function pe(e){if(qe(e))return f(\"The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.\",Be(e)),ue(e)}var D=j.ReactCurrentOwner,ze={key:!0,ref:!0,__self:!0,__source:!0},fe,me,V;V={};function Ge(e){if(S.call(e,\"ref\")){var a=Object.getOwnPropertyDescriptor(e,\"ref\").get;if(a&&a.isReactWarning)return!1}return e.ref!==void 0}function Ke(e){if(S.call(e,\"key\")){var a=Object.getOwnPropertyDescriptor(e,\"key\").get;if(a&&a.isReactWarning)return!1}return e.key!==void 0}function Je(e,a){if(typeof e.ref==\"string\"&&D.current&&a&&D.current.stateNode!==a){var s=_(D.current.type);V[s]||(f('Component \"%s\" contains the string ref \"%s\". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref',_(D.current.type),e.ref),V[s]=!0)}}function Qe(e,a){{var s=function(){fe||(fe=!0,f(\"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)\",a))};s.isReactWarning=!0,Object.defineProperty(e,\"key\",{get:s,configurable:!0})}}function Ze(e,a){{var s=function(){me||(me=!0,f(\"%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)\",a))};s.isReactWarning=!0,Object.defineProperty(e,\"ref\",{get:s,configurable:!0})}}var en=function(e,a,s,t,o,l,d){var i={$$typeof:n,type:e,key:a,ref:s,props:d,_owner:l};return i._store={},Object.defineProperty(i._store,\"validated\",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(i,\"_self\",{configurable:!1,enumerable:!1,writable:!1,value:t}),Object.defineProperty(i,\"_source\",{configurable:!1,enumerable:!1,writable:!1,value:o}),Object.freeze&&(Object.freeze(i.props),Object.freeze(i)),i};function nn(e,a,s,t,o){{var l,d={},i=null,m=null;s!==void 0&&(pe(s),i=\"\"+s),Ke(a)&&(pe(a.key),i=\"\"+a.key),Ge(a)&&(m=a.ref,Je(a,o));for(l in a)S.call(a,l)&&!ze.hasOwnProperty(l)&&(d[l]=a[l]);if(e&&e.defaultProps){var u=e.defaultProps;for(l in u)d[l]===void 0&&(d[l]=u[l])}if(i||m){var p=typeof e==\"function\"?e.displayName||e.name||\"Unknown\":e;i&&Qe(d,p),m&&Ze(d,p)}return en(e,i,m,o,t,D.current,d)}}var $=j.ReactCurrentOwner,he=j.ReactDebugCurrentFrame;function P(e){if(e){var a=e._owner,s=C(e.type,e._source,a?a.type:null);he.setExtraStackFrame(s)}else he.setExtraStackFrame(null)}var X;X=!1;function H(e){return typeof e==\"object\"&&e!==null&&e.$$typeof===n}function be(){{if($.current){var e=_($.current.type);if(e)return`\n\nCheck the render method of \\``+e+\"`.\"}return\"\"}}function rn(e){{if(e!==void 0){var a=e.fileName.replace(/^.*[\\\\\\/]/,\"\"),s=e.lineNumber;return`\n\nCheck your code at `+a+\":\"+s+\".\"}return\"\"}}var _e={};function an(e){{var a=be();if(!a){var s=typeof e==\"string\"?e:e.displayName||e.name;s&&(a=`\n\nCheck the top-level render call using <`+s+\">.\")}return a}}function ge(e,a){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var s=an(a);if(_e[s])return;_e[s]=!0;var t=\"\";e&&e._owner&&e._owner!==$.current&&(t=\" It was passed a child from \"+_(e._owner.type)+\".\"),P(e),f('Each child in a list should have a unique \"key\" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',s,t),P(null)}}function xe(e,a){{if(typeof e!=\"object\")return;if(W(e))for(var s=0;s\",i=\" Did you accidentally export a JSX literal instead of a component?\"):u=typeof e,f(\"React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s\",u,i)}var p=nn(e,a,s,o,l);if(p==null)return p;if(d){var h=a.children;if(h!==void 0)if(t)if(W(h)){for(var k=0;k{\"use strict\";ve.exports=ke()});var Nn={};mn(Nn,{default:()=>xn,frontmatter:()=>_n});var r=hn(De()),_n={title:\"Vercel introducing serverless functions and combining with AWS\",description:\"Vercel is a cloud platform for static sites and Serverless Functions that you can deploy instantly, and scale automatically.\",date:\"2023-4-6\",author:\"Lee Robinson\"};function Le(c){let n=Object.assign({p:\"p\",a:\"a\",h3:\"h3\",ul:\"ul\",li:\"li\",pre:\"pre\",code:\"code\",img:\"img\",h2:\"h2\"},c.components);return(0,r.jsxDEV)(r.Fragment,{children:[(0,r.jsxDEV)(n.p,{children:[\"Here is the \",(0,r.jsxDEV)(n.a,{href:\"https://nextjs-appdir-blog.vercel.app\",children:\"demo\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:8,columnNumber:13},this),\" \\u{1F44B}\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:8,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h3,{children:\"Contents\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:10,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.ul,{children:[`\n`,(0,r.jsxDEV)(n.li,{children:\"Create a Next.js app\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:12,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:[\"Create a blog page with \",(0,r.jsxDEV)(n.a,{href:\"https://contentlayer.dev\",children:\"contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:13,columnNumber:27},this)]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:13,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"Styling the blog\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:14,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"Custom components\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:15,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"List all posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:16,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"Highlight codes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:17,columnNumber:1},this),`\n`]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:12,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h3,{children:\"Let's get started!\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:20,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"First, we need to create a new Next.js app with the new app folder feature:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:22,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npx create-next-app@latest --ts --experimental-app\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:24,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:24,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can also use \",(0,r.jsxDEV)(n.code,{children:\"Javascript\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:28,columnNumber:18},this),\" instead of \",(0,r.jsxDEV)(n.code,{children:\"Typescript\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:28,columnNumber:42},this),\". In this tutorial we will use \",(0,r.jsxDEV)(n.code,{children:\"Typescript\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:28,columnNumber:85},this),\".\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:28,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Then, you need to install the Contentlayer:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:30,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npm i contentlayer next-contentlayer @opentelemetry/api\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:32,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:32,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, export the \",(0,r.jsxDEV)(n.code,{children:\"contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:36,columnNumber:17},this),\" config in the \",(0,r.jsxDEV)(n.code,{children:\"next.config.js\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:36,columnNumber:46},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:36,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-js\",children:`const { withContentlayer } = require('next-contentlayer')\n\nmodule.exports = withContentlayer({\n experimental: { appDir: true },\n})\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:38,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:38,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"contentlayer.config.ts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:46,columnNumber:26},this),\" file in the root of the project and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:46,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-ts\",children:`import { defineDocumentType, makeSource } from \"contentlayer/source-files\";\n\n\nconst Post = defineDocumentType(() => ({\n name: \"Post\",\n filePathPattern: \\`**/*.mdx\\`,\n contentType: \"mdx\",\n fields: {\n title: {\n type: \"string\",\n description: \"The title of the post\",\n required: true,\n },\n description: {\n type: \"string\",\n description: \"The description of the post\",\n required: true,\n },\n },\n computedFields: {\n url: {\n type: \"string\",\n resolve: (doc) => \\`/posts/\\${doc._raw.flattenedPath}\\`,\n },\n },\n}));\n\nexport default makeSource({\n contentDirPath: \"posts\",\n documentTypes: [Post],\n});\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:48,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:48,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Above code is the config for the Contentlayer. It will create a \",(0,r.jsxDEV)(n.code,{children:\"Post\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:83,columnNumber:65},this),\" document type and will generate the \",(0,r.jsxDEV)(n.code,{children:\"url\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:83,columnNumber:108},this),\" field based on the \",(0,r.jsxDEV)(n.code,{children:\"flattenedPath\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:83,columnNumber:133},this),\" field.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:83,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can add more document types and fields such as \",(0,r.jsxDEV)(n.code,{children:\"Author\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:85,columnNumber:52},this),\" and \",(0,r.jsxDEV)(n.code,{children:\"Category\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:85,columnNumber:65},this),\" and more.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:85,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:87,columnNumber:26},this),\" folder in the root of the project and create a \",(0,r.jsxDEV)(n.code,{children:\"hello-world.mdx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:87,columnNumber:81},this),\" file in it and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:87,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-mdx\",children:`---\ntitle: How to create Next.js app\ndescription: Learn how to create Next.js app\n---\n\n# Install Next.js\n\n### Fist you need to install Next.js with the following command:\n\nnpm i create-next-app@latest\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:89,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:89,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Then, restart the app with the following command:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:102,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npm run dev\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:104,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:104,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see new \",(0,r.jsxDEV)(n.code,{children:\".contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:108,columnNumber:22},this),\" folder in the root of the project. This folder contains the generated JSON files, types and more.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:108,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/nrdVwTLt/Screenshot-2023-04-05-at-6-13-25-PM.png\",alt:\"generate contentlayer folder\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:110,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:110,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:112,columnNumber:26},this),\" folder in the \",(0,r.jsxDEV)(n.code,{children:\"app\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:112,columnNumber:48},this),\" folder and create a \",(0,r.jsxDEV)(n.code,{children:\"[slug]\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:112,columnNumber:74},this),\" folder in it. and create a \",(0,r.jsxDEV)(n.code,{children:\"page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:112,columnNumber:110},this),\" file in \",(0,r.jsxDEV)(n.code,{children:\"[slug]\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:112,columnNumber:129},this),\" folder and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:112,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"app/posts/[slug]/page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:115,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:115,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-tsx\",children:`import { allPosts } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\n\nexport const generateStaticParams = async () =>\n\n\n allPosts.map((post) => ({ slug: post._raw.flattenedPath }));\n export const generateMetadata = ({ params }:any) => {\n const post = allPosts.find((post:any) => post._raw.flattenedPath === params.slug)\n return { title: post?.title,description: post?.description }\n }\n\nconst PostLayout = ({ params }: { params: { slug: string } }) => {\n const post = allPosts.find(\n (post) => post._raw.flattenedPath === params.slug\n );\n\n let MDXContent;\n\n if (!post) {\n return
404
;\n } else {\n MDXContent = getMDXComponent(post!.body.code);\n }\n\n return (\n
\n

\n {post.title}\n

\n

{post.description}

\n
\n \n
\n
\n );\n};\n\nexport default PostLayout;\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:117,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:117,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Above code is the page for the blog post. It will render the blog post based on the \",(0,r.jsxDEV)(n.code,{children:\"slug\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:160,columnNumber:85},this),\" parameter.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:160,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see the blog rendered in the \",(0,r.jsxDEV)(n.code,{children:\"http://localhost:3000/posts/hello-world\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:162,columnNumber:43},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:162,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/vHZ5HHC0/Screenshot-2023-04-05-at-6-34-14-PM.png\",alt:\"blog rendered\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:164,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:164,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Styling the blog\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:166,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to style the blog using \",(0,r.jsxDEV)(n.code,{children:\"CSS\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:168,columnNumber:38},this),\" or others. In this tutorial, we will use \",(0,r.jsxDEV)(n.code,{children:\"CSS\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:168,columnNumber:85},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:168,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"globals.css\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:170,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:170,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-css\",children:`pre {\n padding: 15px 20px;\n border-radius: 10px;\n background-color: #f9f8f981;\n overflow: auto;\n font-size: 0.9rem;\n margin: 40px 0;\n}\narticle p {\n font-size: 1rem;\n line-height: 1.8rem;\n margin-top: 20px;\n}\narticle h1 {\n font-size: 2.5rem;\n line-height: 3.5rem;\n margin-top: 60px;\n font-weight: 425;\n}\n\n...\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:172,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:172,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Now, you can see the blog styled:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:197,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/0jr5kM57/Screenshot-2023-04-05-at-8-43-24-PM.png\",alt:\"styled blog\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:199,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:199,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Also you can use \",(0,r.jsxDEV)(n.code,{children:\"TailwindCSS\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:201,columnNumber:18},this),\" or others.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:201,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Custom components\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:203,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Custom components is a great feature of \",(0,r.jsxDEV)(n.code,{children:\"MDX\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:205,columnNumber:41},this),\". You can create your own components and use them in your blog posts.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:205,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"For example, we can create a \",(0,r.jsxDEV)(n.code,{children:\"CodeSnippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:207,columnNumber:30},this),\" component:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:207,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"app/posts/[slug]/page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:209,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:209,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-tsx\",children:`import { allWritings } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\nimport { Snippet } from \"@geist-ui/core\";\n\n...\n\nconst CodeSnippet = (props: any) => (\n \n);\n\n return (\n
\n

\n {writing.title}\n

\n

{writing.description}

\n
\n \n
\n
\n );\n\nexport default PostLayout;\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:212,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:212,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can use the \",(0,r.jsxDEV)(n.code,{children:\"CodeSnippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:238,columnNumber:22},this),\" component in your blog posts:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:238,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-mdx\",children:`---\ntitle: How to create a Next.js app\ndescription: Learn how to create a Next.js app\n---\n\n# Install Next.js\n\n### First, install Next.js using the following command:\n\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:240,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:240,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see the \",(0,r.jsxDEV)(n.code,{children:\"CodeSnippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:253,columnNumber:22},this),\" component in the blog post:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:253,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/MT7756nQ/Screenshot-2023-04-05-at-9-33-21-PM.png\",alt:\"code snippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:255,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:255,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"List all posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:257,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a page that lists all posts. For this, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:259,columnNumber:83},this),\" folder in the \",(0,r.jsxDEV)(n.code,{children:\"app\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:259,columnNumber:105},this),\" folder and create a \",(0,r.jsxDEV)(n.code,{children:\"page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:259,columnNumber:131},this),\" file in it and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:259,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"app/posts/page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:261,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:261,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-tsx\",children:`import Link from 'next/link'\nimport { allPosts, Post } from 'contentlayer/generated'\n\nfunction PostCard(post: Post) {\n return (\n
\n

\n \n {post.title}\n \n

\n

{post.description}

\n
\n )\n}\n\nfunction page() {\n const posts = allPosts\n\n return (\n
\n
\n {posts.map((post, idx) => (\n \n ))}\n
\n
\n )\n}\n\nexport default page;\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:263,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:263,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see the list of all posts in the \",(0,r.jsxDEV)(n.code,{children:\"http://localhost:3000/posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:297,columnNumber:47},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:297,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/LsRQMbjL/Screenshot-2023-04-05-at-10-23-37-PM.png\",alt:\"list of all posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:299,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:299,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Highlight codes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:301,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to highlight the codes in the blog posts. For this, we will use \",(0,r.jsxDEV)(n.code,{children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:303,columnNumber:78},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:303,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npm i rehype-pretty-code shiki\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:305,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:305,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to add the \",(0,r.jsxDEV)(n.code,{children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:309,columnNumber:25},this),\" plugin to the \",(0,r.jsxDEV)(n.code,{children:\"contentlayer.config.ts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:309,columnNumber:60},this),\" file:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:309,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"contentlayer.config.ts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:311,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:311,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-ts\",children:`import { defineDocumentType, makeSource } from \"contentlayer/source-files\";\nimport rehypePrettyCode from \"rehype-pretty-code\";\n\nconst Writing = defineDocumentType(() => ({\n ...\n}));\n\nconst rehypeoptions = {\n // Use one of Shiki's packaged themes\n theme: \"light-plus\",\n // Set to true to keep the background color\n keepBackground: true ,\n onVisitLine(node: any) {\n if (node.children.length === 0) {\n node.children = [{ type: \"text\", value: \" \" }];\n }\n },\n onVisitHighlightedLine(node: any) {\n node.properties.className.push(\"highlighted\");\n },\n onVisitHighlightedWord(node: any, id: any) {\n node.properties.className = [\"word\"];\n },\n };\n\nexport default makeSource({\n contentDirPath: \"writings\",\n documentTypes: [Writing],\n mdx: {\n rehypePlugins: [[rehypePrettyCode, rehypeoptions]],\n },\n});\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:313,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:313,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Now, you can see the highlighted codes in the blog posts:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:349,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/mrPYKxrm/Screenshot-2023-04-05-at-10-44-36-PM.png\",alt:\"highlighted codes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:351,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:351,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can find more information about \",(0,r.jsxDEV)(n.a,{href:\"https://rehype-pretty-code.netlify.app/\",children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:353,columnNumber:37},this),`\nand `,(0,r.jsxDEV)(n.a,{href:\"https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes\",children:\"Shiki themes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:354,columnNumber:5},this),\".\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:353,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Conclusion\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:356,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"In this tutorial, we have learned how to create a blog using \",(0,r.jsxDEV)(n.code,{children:\"Next.js\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:358,columnNumber:62},this),\", \",(0,r.jsxDEV)(n.code,{children:\"Contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:358,columnNumber:73},this),\", and \",(0,r.jsxDEV)(n.code,{children:\"MDX\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:358,columnNumber:93},this),\". We have learned how to create a blog post, how to list all posts, and how to highlight codes in the blog posts.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:358,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can find the source code of the \",(0,r.jsxDEV)(n.code,{children:\"Contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:360,columnNumber:37},this),\" blog in the following GitHub repository:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:360,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.a,{href:\"https://github.com/contentlayerdev/next-contentlayer-example\",children:\"Source code of example\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:362,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:362,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Resources\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:364,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.ul,{children:[`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://contentlayer.dev/\",children:\"Contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:366,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:366,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://nextjs.org/\",children:\"Next.js\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:367,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:367,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://mdxjs.com/\",children:\"MDX\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:368,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:368,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://rehype-pretty-code.netlify.app/\",children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:369,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:369,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes\",children:\"Shiki themes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:370,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:370,columnNumber:1},this),`\n`]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:366,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"About the author\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:372,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[(0,r.jsxDEV)(n.a,{href:\"https://arshadd.site\",children:\"Arshad Yaseen\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:374,columnNumber:1},this),\". I'm a software engineer and I love to create aesthetic frontends. If you have any questions, feel free to ask me on \",(0,r.jsxDEV)(n.a,{href:\"https://twitter.com/arshadyaseeen\",children:\"Twitter\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:374,columnNumber:156},this),\".\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:374,columnNumber:1},this)]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\",lineNumber:1,columnNumber:1},this)}function gn(c={}){let{wrapper:n}=c.components||{};return n?(0,r.jsxDEV)(n,Object.assign({},c,{children:(0,r.jsxDEV)(Le,c,void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\"},this)}),void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-0d8a11fc-4ef0-4917-a776-35a051cc0da6.mdx\"},this):Le(c)}var xn=gn;return bn(Nn);})();\n/*! Bundled license information:\n\nreact/cjs/react-jsx-dev-runtime.development.js:\n (**\n * @license React\n * react-jsx-dev-runtime.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *)\n*/\n;return Component;" 12 | }, 13 | "_id": "vercel-aws.mdx", 14 | "_raw": { 15 | "sourceFilePath": "vercel-aws.mdx", 16 | "sourceFileName": "vercel-aws.mdx", 17 | "sourceFileDir": ".", 18 | "contentType": "mdx", 19 | "flattenedPath": "vercel-aws" 20 | }, 21 | "type": "Post", 22 | "url": "/posts/vercel-aws" 23 | }, 24 | "documentHash": "1680793292013", 25 | "hasWarnings": false, 26 | "documentTypeName": "Post" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.contentlayer/.cache/v0.3.1/data-DQZJDV74.json: -------------------------------------------------------------------------------- 1 | { 2 | "cacheItemsMap": { 3 | "vercel-aws.mdx": { 4 | "document": { 5 | "title": "Vercel introducing serverless functions and combining with AWS", 6 | "description": "Vercel is a cloud platform for static sites and Serverless Functions that you can deploy instantly, and scale automatically.", 7 | "date": "2023-04-05T18:30:00.000Z", 8 | "author": "Lee Robinson", 9 | "body": { 10 | "raw": "\nHere is the [demo](https://nextjs-appdir-blog.vercel.app) 👋\n\n### Contents\n\n- Create a Next.js app\n- Create a blog page with [contentlayer](https://contentlayer.dev)\n- Styling the blog\n- Custom components\n- List all posts\n- Highlight codes\n\n\n### Let's get started!\n\nFirst, we need to create a new Next.js app with the new app folder feature:\n\n```bash\nnpx create-next-app@latest --ts --experimental-app\n```\n\nYou can also use `Javascript` instead of `Typescript`. In this tutorial we will use `Typescript`.\n\nThen, you need to install the Contentlayer:\n\n```bash\nnpm i contentlayer next-contentlayer @opentelemetry/api\n```\n\nNow, export the `contentlayer` config in the `next.config.js`:\n\n```js\nconst { withContentlayer } = require('next-contentlayer')\n\nmodule.exports = withContentlayer({\n experimental: { appDir: true },\n})\n```\n\nNow, we need to create a `contentlayer.config.ts` file in the root of the project and add the following code:\n\n```ts\nimport { defineDocumentType, makeSource } from \"contentlayer/source-files\";\n\n\nconst Post = defineDocumentType(() => ({\n name: \"Post\",\n filePathPattern: `**/*.mdx`,\n contentType: \"mdx\",\n fields: {\n title: {\n type: \"string\",\n description: \"The title of the post\",\n required: true,\n },\n description: {\n type: \"string\",\n description: \"The description of the post\",\n required: true,\n },\n },\n computedFields: {\n url: {\n type: \"string\",\n resolve: (doc) => `/posts/${doc._raw.flattenedPath}`,\n },\n },\n}));\n\nexport default makeSource({\n contentDirPath: \"posts\",\n documentTypes: [Post],\n});\n\n```\n\nAbove code is the config for the Contentlayer. It will create a `Post` document type and will generate the `url` field based on the `flattenedPath` field.\n\nYou can add more document types and fields such as `Author` and `Category` and more.\n\nNow, we need to create a `posts` folder in the root of the project and create a `hello-world.mdx` file in it and add the following code:\n\n```mdx\n---\ntitle: How to create Next.js app\ndescription: Learn how to create Next.js app\n---\n\n# Install Next.js\n\n### Fist you need to install Next.js with the following command:\n\nnpm i create-next-app@latest\n```\n\nThen, restart the app with the following command:\n\n```bash\nnpm run dev\n```\n\nNow, you can see new `.contentlayer` folder in the root of the project. This folder contains the generated JSON files, types and more.\n\n![generate contentlayer folder](https://i.postimg.cc/nrdVwTLt/Screenshot-2023-04-05-at-6-13-25-PM.png)\n\nNow, we need to create a `posts` folder in the `app` folder and create a `[slug]` folder in it. and create a `page.tsx` file in `[slug]` folder and add the following code:\n\n\n`app/posts/[slug]/page.tsx`\n\n```tsx\nimport { allPosts } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\n\nexport const generateStaticParams = async () =>\n\n\n allPosts.map((post) => ({ slug: post._raw.flattenedPath }));\n export const generateMetadata = ({ params }:any) => {\n const post = allPosts.find((post:any) => post._raw.flattenedPath === params.slug)\n return { title: post?.title,description: post?.description }\n }\n\nconst PostLayout = ({ params }: { params: { slug: string } }) => {\n const post = allPosts.find(\n (post) => post._raw.flattenedPath === params.slug\n );\n\n let MDXContent;\n\n if (!post) {\n return
404
;\n } else {\n MDXContent = getMDXComponent(post!.body.code);\n }\n\n return (\n
\n

\n {post.title}\n

\n

{post.description}

\n
\n \n
\n
\n );\n};\n\nexport default PostLayout;\n\n```\n\nAbove code is the page for the blog post. It will render the blog post based on the `slug` parameter.\n\nNow, you can see the blog rendered in the `http://localhost:3000/posts/hello-world`:\n\n![blog rendered](https://i.postimg.cc/vHZ5HHC0/Screenshot-2023-04-05-at-6-34-14-PM.png)\n\n## Styling the blog\n\nNow, we need to style the blog using `CSS` or others. In this tutorial, we will use `CSS`:\n\n`globals.css`\n\n```css\npre {\n padding: 15px 20px;\n border-radius: 10px;\n background-color: #f9f8f981;\n overflow: auto;\n font-size: 0.9rem;\n margin: 40px 0;\n}\narticle p {\n font-size: 1rem;\n line-height: 1.8rem;\n margin-top: 20px;\n}\narticle h1 {\n font-size: 2.5rem;\n line-height: 3.5rem;\n margin-top: 60px;\n font-weight: 425;\n}\n\n...\n\n```\n\nNow, you can see the blog styled:\n\n![styled blog](https://i.postimg.cc/0jr5kM57/Screenshot-2023-04-05-at-8-43-24-PM.png)\n\nAlso you can use `TailwindCSS` or others.\n\n## Custom components\n\nCustom components is a great feature of `MDX`. You can create your own components and use them in your blog posts.\n\nFor example, we can create a `CodeSnippet` component:\n\n`app/posts/[slug]/page.tsx`\n\n\n```tsx\nimport { allWritings } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\nimport { Snippet } from \"@geist-ui/core\";\n\n...\n\nconst CodeSnippet = (props: any) => (\n \n);\n\n return (\n
\n

\n {writing.title}\n

\n

{writing.description}

\n
\n \n
\n
\n );\n\nexport default PostLayout;\n```\n\nNow, you can use the `CodeSnippet` component in your blog posts:\n\n```mdx\n---\ntitle: How to create a Next.js app\ndescription: Learn how to create a Next.js app\n---\n\n# Install Next.js\n\n### First, install Next.js using the following command:\n\n\n```\n\nNow, you can see the `CodeSnippet` component in the blog post:\n\n![code snippet](https://i.postimg.cc/MT7756nQ/Screenshot-2023-04-05-at-9-33-21-PM.png)\n\n## List all posts\n\nNow, we need to create a page that lists all posts. For this, we need to create a `posts` folder in the `app` folder and create a `page.tsx` file in it and add the following code:\n\n`app/posts/page.tsx`\n\n```tsx\nimport Link from 'next/link'\nimport { allPosts, Post } from 'contentlayer/generated'\n\nfunction PostCard(post: Post) {\n return (\n
\n

\n \n {post.title}\n \n

\n

{post.description}

\n
\n )\n}\n\nfunction page() {\n const posts = allPosts\n\n return (\n
\n
\n {posts.map((post, idx) => (\n \n ))}\n
\n
\n )\n}\n\nexport default page;\n```\n\nNow, you can see the list of all posts in the `http://localhost:3000/posts`:\n\n![list of all posts](https://i.postimg.cc/LsRQMbjL/Screenshot-2023-04-05-at-10-23-37-PM.png)\n\n## Highlight codes\n\nNow, we need to highlight the codes in the blog posts. For this, we will use `rehype-pretty-code`:\n\n```bash\nnpm i rehype-pretty-code shiki\n```\n\nNow, we need to add the `rehype-pretty-code` plugin to the `contentlayer.config.ts` file:\n\n`contentlayer.config.ts`\n\n```ts\nimport { defineDocumentType, makeSource } from \"contentlayer/source-files\";\nimport rehypePrettyCode from \"rehype-pretty-code\";\n\nconst Writing = defineDocumentType(() => ({\n ...\n}));\n\nconst rehypeoptions = {\n // Use one of Shiki's packaged themes\n theme: \"light-plus\",\n // Set to true to keep the background color\n keepBackground: true ,\n onVisitLine(node: any) {\n if (node.children.length === 0) {\n node.children = [{ type: \"text\", value: \" \" }];\n }\n },\n onVisitHighlightedLine(node: any) {\n node.properties.className.push(\"highlighted\");\n },\n onVisitHighlightedWord(node: any, id: any) {\n node.properties.className = [\"word\"];\n },\n };\n\nexport default makeSource({\n contentDirPath: \"writings\",\n documentTypes: [Writing],\n mdx: {\n rehypePlugins: [[rehypePrettyCode, rehypeoptions]],\n },\n});\n\n```\n\nNow, you can see the highlighted codes in the blog posts:\n\n![highlighted codes](https://i.postimg.cc/mrPYKxrm/Screenshot-2023-04-05-at-10-44-36-PM.png)\n\nYou can find more information about [rehype-pretty-code](https://rehype-pretty-code.netlify.app/)\nand [Shiki themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes).\n\n## Conclusion\n\nIn this tutorial, we have learned how to create a blog using `Next.js`, `Contentlayer`, and `MDX`. We have learned how to create a blog post, how to list all posts, and how to highlight codes in the blog posts.\n\nYou can find the source code of the `Contentlayer` blog in the following GitHub repository:\n\n[Source code of example](https://github.com/contentlayerdev/next-contentlayer-example)\n\n## Resources\n\n- [Contentlayer](https://contentlayer.dev/)\n- [Next.js](https://nextjs.org/)\n- [MDX](https://mdxjs.com/)\n- [rehype-pretty-code](https://rehype-pretty-code.netlify.app/)\n- [Shiki themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes)\n\n## About the author\n\n[Arshad Yaseen](https://arshadd.site). I'm a software engineer and I love to create aesthetic frontends. If you have any questions, feel free to ask me on [Twitter](https://twitter.com/arshadyaseeen).", 11 | "code": "var Component=(()=>{var ln=Object.create;var T=Object.defineProperty;var un=Object.getOwnPropertyDescriptor;var pn=Object.getOwnPropertyNames;var cn=Object.getPrototypeOf,fn=Object.prototype.hasOwnProperty;var B=(u,n)=>()=>(n||u((n={exports:{}}).exports,n),n.exports),mn=(u,n)=>{for(var h in n)T(u,h,{get:n[h],enumerable:!0})},ye=(u,n,h,N)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let x of pn(n))!fn.call(u,x)&&x!==h&&T(u,x,{get:()=>n[x],enumerable:!(N=un(n,x))||N.enumerable});return u};var bn=(u,n,h)=>(h=u!=null?ln(cn(u)):{},ye(n||!u||!u.__esModule?T(h,\"default\",{value:u,enumerable:!0}):h,u)),hn=u=>ye(T({},\"__esModule\",{value:!0}),u);var Pe=B((jn,je)=>{je.exports=React});var ke=B(q=>{\"use strict\";(function(){\"use strict\";var u=Pe(),n=Symbol.for(\"react.element\"),h=Symbol.for(\"react.portal\"),N=Symbol.for(\"react.fragment\"),x=Symbol.for(\"react.strict_mode\"),z=Symbol.for(\"react.profiler\"),G=Symbol.for(\"react.provider\"),K=Symbol.for(\"react.context\"),L=Symbol.for(\"react.forward_ref\"),O=Symbol.for(\"react.suspense\"),F=Symbol.for(\"react.suspense_list\"),U=Symbol.for(\"react.memo\"),A=Symbol.for(\"react.lazy\"),Ue=Symbol.for(\"react.offscreen\"),J=Symbol.iterator,we=\"@@iterator\";function Ee(e){if(e===null||typeof e!=\"object\")return null;var a=J&&e[J]||e[we];return typeof a==\"function\"?a:null}var j=u.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function f(e){{for(var a=arguments.length,s=new Array(a>1?a-1:0),t=1;t=1&&c>=0&&d[p]!==m[c];)c--;for(;p>=1&&c>=0;p--,c--)if(d[p]!==m[c]){if(p!==1||c!==1)do if(p--,c--,c<0||d[p]!==m[c]){var b=`\n`+d[p].replace(\" at new \",\" at \");return e.displayName&&b.includes(\"\")&&(b=b.replace(\"\",e.displayName)),typeof e==\"function\"&&E.set(e,b),b}while(p>=1&&c>=0);break}}}finally{Y=!1,M.current=l,Ye(),Error.prepareStackTrace=o}var k=e?e.displayName||e.name:\"\",Ne=k?w(k):\"\";return typeof e==\"function\"&&E.set(e,Ne),Ne}function Ve(e,a,s){return oe(e,!1)}function $e(e){var a=e.prototype;return!!(a&&a.isReactComponent)}function C(e,a,s){if(e==null)return\"\";if(typeof e==\"function\")return oe(e,$e(e));if(typeof e==\"string\")return w(e);switch(e){case O:return w(\"Suspense\");case F:return w(\"SuspenseList\")}if(typeof e==\"object\")switch(e.$$typeof){case L:return Ve(e.render);case U:return C(e.type,a,s);case A:{var t=e,o=t._payload,l=t._init;try{return C(l(o),a,s)}catch{}}}return\"\"}var S=Object.prototype.hasOwnProperty,le={},ue=j.ReactDebugCurrentFrame;function R(e){if(e){var a=e._owner,s=C(e.type,e._source,a?a.type:null);ue.setExtraStackFrame(s)}else ue.setExtraStackFrame(null)}function Xe(e,a,s,t,o){{var l=Function.call.bind(S);for(var i in e)if(l(e,i)){var d=void 0;try{if(typeof e[i]!=\"function\"){var m=Error((t||\"React class\")+\": \"+s+\" type `\"+i+\"` is invalid; it must be a function, usually from the `prop-types` package, but received `\"+typeof e[i]+\"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.\");throw m.name=\"Invariant Violation\",m}d=e[i](a,i,t,s,null,\"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED\")}catch(p){d=p}d&&!(d instanceof Error)&&(R(o),f(\"%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).\",t||\"React class\",s,i,typeof d),R(null)),d instanceof Error&&!(d.message in le)&&(le[d.message]=!0,R(o),f(\"Failed %s type: %s\",s,d.message),R(null))}}}var He=Array.isArray;function W(e){return He(e)}function Be(e){{var a=typeof Symbol==\"function\"&&Symbol.toStringTag,s=a&&e[Symbol.toStringTag]||e.constructor.name||\"Object\";return s}}function qe(e){try{return pe(e),!1}catch{return!0}}function pe(e){return\"\"+e}function ce(e){if(qe(e))return f(\"The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.\",Be(e)),pe(e)}var D=j.ReactCurrentOwner,ze={key:!0,ref:!0,__self:!0,__source:!0},fe,me,V;V={};function Ge(e){if(S.call(e,\"ref\")){var a=Object.getOwnPropertyDescriptor(e,\"ref\").get;if(a&&a.isReactWarning)return!1}return e.ref!==void 0}function Ke(e){if(S.call(e,\"key\")){var a=Object.getOwnPropertyDescriptor(e,\"key\").get;if(a&&a.isReactWarning)return!1}return e.key!==void 0}function Je(e,a){if(typeof e.ref==\"string\"&&D.current&&a&&D.current.stateNode!==a){var s=_(D.current.type);V[s]||(f('Component \"%s\" contains the string ref \"%s\". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref',_(D.current.type),e.ref),V[s]=!0)}}function Qe(e,a){{var s=function(){fe||(fe=!0,f(\"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)\",a))};s.isReactWarning=!0,Object.defineProperty(e,\"key\",{get:s,configurable:!0})}}function Ze(e,a){{var s=function(){me||(me=!0,f(\"%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)\",a))};s.isReactWarning=!0,Object.defineProperty(e,\"ref\",{get:s,configurable:!0})}}var en=function(e,a,s,t,o,l,i){var d={$$typeof:n,type:e,key:a,ref:s,props:i,_owner:l};return d._store={},Object.defineProperty(d._store,\"validated\",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(d,\"_self\",{configurable:!1,enumerable:!1,writable:!1,value:t}),Object.defineProperty(d,\"_source\",{configurable:!1,enumerable:!1,writable:!1,value:o}),Object.freeze&&(Object.freeze(d.props),Object.freeze(d)),d};function nn(e,a,s,t,o){{var l,i={},d=null,m=null;s!==void 0&&(ce(s),d=\"\"+s),Ke(a)&&(ce(a.key),d=\"\"+a.key),Ge(a)&&(m=a.ref,Je(a,o));for(l in a)S.call(a,l)&&!ze.hasOwnProperty(l)&&(i[l]=a[l]);if(e&&e.defaultProps){var p=e.defaultProps;for(l in p)i[l]===void 0&&(i[l]=p[l])}if(d||m){var c=typeof e==\"function\"?e.displayName||e.name||\"Unknown\":e;d&&Qe(i,c),m&&Ze(i,c)}return en(e,d,m,o,t,D.current,i)}}var $=j.ReactCurrentOwner,be=j.ReactDebugCurrentFrame;function P(e){if(e){var a=e._owner,s=C(e.type,e._source,a?a.type:null);be.setExtraStackFrame(s)}else be.setExtraStackFrame(null)}var X;X=!1;function H(e){return typeof e==\"object\"&&e!==null&&e.$$typeof===n}function he(){{if($.current){var e=_($.current.type);if(e)return`\n\nCheck the render method of \\``+e+\"`.\"}return\"\"}}function rn(e){{if(e!==void 0){var a=e.fileName.replace(/^.*[\\\\\\/]/,\"\"),s=e.lineNumber;return`\n\nCheck your code at `+a+\":\"+s+\".\"}return\"\"}}var _e={};function an(e){{var a=he();if(!a){var s=typeof e==\"string\"?e:e.displayName||e.name;s&&(a=`\n\nCheck the top-level render call using <`+s+\">.\")}return a}}function ge(e,a){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var s=an(a);if(_e[s])return;_e[s]=!0;var t=\"\";e&&e._owner&&e._owner!==$.current&&(t=\" It was passed a child from \"+_(e._owner.type)+\".\"),P(e),f('Each child in a list should have a unique \"key\" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',s,t),P(null)}}function xe(e,a){{if(typeof e!=\"object\")return;if(W(e))for(var s=0;s\",d=\" Did you accidentally export a JSX literal instead of a component?\"):p=typeof e,f(\"React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s\",p,d)}var c=nn(e,a,s,o,l);if(c==null)return c;if(i){var b=a.children;if(b!==void 0)if(t)if(W(b)){for(var k=0;k{\"use strict\";ve.exports=ke()});var Nn={};mn(Nn,{default:()=>xn,frontmatter:()=>_n});var r=bn(De()),_n={title:\"Vercel introducing serverless functions and combining with AWS\",description:\"Vercel is a cloud platform for static sites and Serverless Functions that you can deploy instantly, and scale automatically.\",date:\"2023-4-6\",author:\"Lee Robinson\"};function Le(u){let n=Object.assign({p:\"p\",a:\"a\",h3:\"h3\",ul:\"ul\",li:\"li\",pre:\"pre\",code:\"code\",img:\"img\",h2:\"h2\"},u.components);return(0,r.jsxDEV)(r.Fragment,{children:[(0,r.jsxDEV)(n.p,{children:[\"Here is the \",(0,r.jsxDEV)(n.a,{href:\"https://nextjs-appdir-blog.vercel.app\",children:\"demo\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:8,columnNumber:13},this),\" \\u{1F44B}\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:8,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h3,{children:\"Contents\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:10,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.ul,{children:[`\n`,(0,r.jsxDEV)(n.li,{children:\"Create a Next.js app\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:12,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:[\"Create a blog page with \",(0,r.jsxDEV)(n.a,{href:\"https://contentlayer.dev\",children:\"contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:13,columnNumber:27},this)]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:13,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"Styling the blog\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:14,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"Custom components\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:15,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"List all posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:16,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:\"Highlight codes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:17,columnNumber:1},this),`\n`]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:12,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h3,{children:\"Let's get started!\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:20,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"First, we need to create a new Next.js app with the new app folder feature:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:22,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npx create-next-app@latest --ts --experimental-app\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:24,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:24,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can also use \",(0,r.jsxDEV)(n.code,{children:\"Javascript\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:28,columnNumber:18},this),\" instead of \",(0,r.jsxDEV)(n.code,{children:\"Typescript\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:28,columnNumber:42},this),\". In this tutorial we will use \",(0,r.jsxDEV)(n.code,{children:\"Typescript\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:28,columnNumber:85},this),\".\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:28,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Then, you need to install the Contentlayer:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:30,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npm i contentlayer next-contentlayer @opentelemetry/api\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:32,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:32,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, export the \",(0,r.jsxDEV)(n.code,{children:\"contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:36,columnNumber:17},this),\" config in the \",(0,r.jsxDEV)(n.code,{children:\"next.config.js\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:36,columnNumber:46},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:36,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-js\",children:`const { withContentlayer } = require('next-contentlayer')\n\nmodule.exports = withContentlayer({\n experimental: { appDir: true },\n})\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:38,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:38,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"contentlayer.config.ts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:46,columnNumber:26},this),\" file in the root of the project and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:46,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-ts\",children:`import { defineDocumentType, makeSource } from \"contentlayer/source-files\";\n\n\nconst Post = defineDocumentType(() => ({\n name: \"Post\",\n filePathPattern: \\`**/*.mdx\\`,\n contentType: \"mdx\",\n fields: {\n title: {\n type: \"string\",\n description: \"The title of the post\",\n required: true,\n },\n description: {\n type: \"string\",\n description: \"The description of the post\",\n required: true,\n },\n },\n computedFields: {\n url: {\n type: \"string\",\n resolve: (doc) => \\`/posts/\\${doc._raw.flattenedPath}\\`,\n },\n },\n}));\n\nexport default makeSource({\n contentDirPath: \"posts\",\n documentTypes: [Post],\n});\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:48,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:48,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Above code is the config for the Contentlayer. It will create a \",(0,r.jsxDEV)(n.code,{children:\"Post\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:83,columnNumber:65},this),\" document type and will generate the \",(0,r.jsxDEV)(n.code,{children:\"url\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:83,columnNumber:108},this),\" field based on the \",(0,r.jsxDEV)(n.code,{children:\"flattenedPath\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:83,columnNumber:133},this),\" field.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:83,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can add more document types and fields such as \",(0,r.jsxDEV)(n.code,{children:\"Author\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:85,columnNumber:52},this),\" and \",(0,r.jsxDEV)(n.code,{children:\"Category\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:85,columnNumber:65},this),\" and more.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:85,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:87,columnNumber:26},this),\" folder in the root of the project and create a \",(0,r.jsxDEV)(n.code,{children:\"hello-world.mdx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:87,columnNumber:81},this),\" file in it and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:87,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-mdx\",children:`---\ntitle: How to create Next.js app\ndescription: Learn how to create Next.js app\n---\n\n# Install Next.js\n\n### Fist you need to install Next.js with the following command:\n\nnpm i create-next-app@latest\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:89,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:89,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Then, restart the app with the following command:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:102,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npm run dev\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:104,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:104,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see new \",(0,r.jsxDEV)(n.code,{children:\".contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:108,columnNumber:22},this),\" folder in the root of the project. This folder contains the generated JSON files, types and more.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:108,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/nrdVwTLt/Screenshot-2023-04-05-at-6-13-25-PM.png\",alt:\"generate contentlayer folder\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:110,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:110,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:112,columnNumber:26},this),\" folder in the \",(0,r.jsxDEV)(n.code,{children:\"app\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:112,columnNumber:48},this),\" folder and create a \",(0,r.jsxDEV)(n.code,{children:\"[slug]\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:112,columnNumber:74},this),\" folder in it. and create a \",(0,r.jsxDEV)(n.code,{children:\"page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:112,columnNumber:110},this),\" file in \",(0,r.jsxDEV)(n.code,{children:\"[slug]\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:112,columnNumber:129},this),\" folder and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:112,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"app/posts/[slug]/page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:115,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:115,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-tsx\",children:`import { allPosts } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\n\nexport const generateStaticParams = async () =>\n\n\n allPosts.map((post) => ({ slug: post._raw.flattenedPath }));\n export const generateMetadata = ({ params }:any) => {\n const post = allPosts.find((post:any) => post._raw.flattenedPath === params.slug)\n return { title: post?.title,description: post?.description }\n }\n\nconst PostLayout = ({ params }: { params: { slug: string } }) => {\n const post = allPosts.find(\n (post) => post._raw.flattenedPath === params.slug\n );\n\n let MDXContent;\n\n if (!post) {\n return
404
;\n } else {\n MDXContent = getMDXComponent(post!.body.code);\n }\n\n return (\n
\n

\n {post.title}\n

\n

{post.description}

\n
\n \n
\n
\n );\n};\n\nexport default PostLayout;\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:117,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:117,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Above code is the page for the blog post. It will render the blog post based on the \",(0,r.jsxDEV)(n.code,{children:\"slug\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:160,columnNumber:85},this),\" parameter.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:160,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see the blog rendered in the \",(0,r.jsxDEV)(n.code,{children:\"http://localhost:3000/posts/hello-world\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:162,columnNumber:43},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:162,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/vHZ5HHC0/Screenshot-2023-04-05-at-6-34-14-PM.png\",alt:\"blog rendered\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:164,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:164,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Styling the blog\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:166,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to style the blog using \",(0,r.jsxDEV)(n.code,{children:\"CSS\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:168,columnNumber:38},this),\" or others. In this tutorial, we will use \",(0,r.jsxDEV)(n.code,{children:\"CSS\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:168,columnNumber:85},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:168,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"globals.css\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:170,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:170,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-css\",children:`pre {\n padding: 15px 20px;\n border-radius: 10px;\n background-color: #f9f8f981;\n overflow: auto;\n font-size: 0.9rem;\n margin: 40px 0;\n}\narticle p {\n font-size: 1rem;\n line-height: 1.8rem;\n margin-top: 20px;\n}\narticle h1 {\n font-size: 2.5rem;\n line-height: 3.5rem;\n margin-top: 60px;\n font-weight: 425;\n}\n\n...\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:172,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:172,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Now, you can see the blog styled:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:197,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/0jr5kM57/Screenshot-2023-04-05-at-8-43-24-PM.png\",alt:\"styled blog\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:199,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:199,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Also you can use \",(0,r.jsxDEV)(n.code,{children:\"TailwindCSS\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:201,columnNumber:18},this),\" or others.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:201,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Custom components\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:203,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Custom components is a great feature of \",(0,r.jsxDEV)(n.code,{children:\"MDX\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:205,columnNumber:41},this),\". You can create your own components and use them in your blog posts.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:205,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"For example, we can create a \",(0,r.jsxDEV)(n.code,{children:\"CodeSnippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:207,columnNumber:30},this),\" component:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:207,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"app/posts/[slug]/page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:209,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:209,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-tsx\",children:`import { allWritings } from \"contentlayer/generated\";\nimport { getMDXComponent } from \"next-contentlayer/hooks\";\nimport { Snippet } from \"@geist-ui/core\";\n\n...\n\nconst CodeSnippet = (props: any) => (\n \n);\n\n return (\n
\n

\n {writing.title}\n

\n

{writing.description}

\n
\n \n
\n
\n );\n\nexport default PostLayout;\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:212,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:212,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can use the \",(0,r.jsxDEV)(n.code,{children:\"CodeSnippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:238,columnNumber:22},this),\" component in your blog posts:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:238,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-mdx\",children:`---\ntitle: How to create a Next.js app\ndescription: Learn how to create a Next.js app\n---\n\n# Install Next.js\n\n### First, install Next.js using the following command:\n\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:240,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:240,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see the \",(0,r.jsxDEV)(n.code,{children:\"CodeSnippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:253,columnNumber:22},this),\" component in the blog post:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:253,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/MT7756nQ/Screenshot-2023-04-05-at-9-33-21-PM.png\",alt:\"code snippet\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:255,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:255,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"List all posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:257,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to create a page that lists all posts. For this, we need to create a \",(0,r.jsxDEV)(n.code,{children:\"posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:259,columnNumber:83},this),\" folder in the \",(0,r.jsxDEV)(n.code,{children:\"app\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:259,columnNumber:105},this),\" folder and create a \",(0,r.jsxDEV)(n.code,{children:\"page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:259,columnNumber:131},this),\" file in it and add the following code:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:259,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"app/posts/page.tsx\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:261,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:261,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-tsx\",children:`import Link from 'next/link'\nimport { allPosts, Post } from 'contentlayer/generated'\n\nfunction PostCard(post: Post) {\n return (\n
\n

\n \n {post.title}\n \n

\n

{post.description}

\n
\n )\n}\n\nfunction page() {\n const posts = allPosts\n\n return (\n
\n
\n {posts.map((post, idx) => (\n \n ))}\n
\n
\n )\n}\n\nexport default page;\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:263,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:263,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, you can see the list of all posts in the \",(0,r.jsxDEV)(n.code,{children:\"http://localhost:3000/posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:297,columnNumber:47},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:297,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/LsRQMbjL/Screenshot-2023-04-05-at-10-23-37-PM.png\",alt:\"list of all posts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:299,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:299,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Highlight codes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:301,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to highlight the codes in the blog posts. For this, we will use \",(0,r.jsxDEV)(n.code,{children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:303,columnNumber:78},this),\":\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:303,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-bash\",children:`npm i rehype-pretty-code shiki\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:305,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:305,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"Now, we need to add the \",(0,r.jsxDEV)(n.code,{children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:309,columnNumber:25},this),\" plugin to the \",(0,r.jsxDEV)(n.code,{children:\"contentlayer.config.ts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:309,columnNumber:60},this),\" file:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:309,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.code,{children:\"contentlayer.config.ts\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:311,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:311,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.pre,{children:(0,r.jsxDEV)(n.code,{className:\"language-ts\",children:`import { defineDocumentType, makeSource } from \"contentlayer/source-files\";\nimport rehypePrettyCode from \"rehype-pretty-code\";\n\nconst Writing = defineDocumentType(() => ({\n ...\n}));\n\nconst rehypeoptions = {\n // Use one of Shiki's packaged themes\n theme: \"light-plus\",\n // Set to true to keep the background color\n keepBackground: true ,\n onVisitLine(node: any) {\n if (node.children.length === 0) {\n node.children = [{ type: \"text\", value: \" \" }];\n }\n },\n onVisitHighlightedLine(node: any) {\n node.properties.className.push(\"highlighted\");\n },\n onVisitHighlightedWord(node: any, id: any) {\n node.properties.className = [\"word\"];\n },\n };\n\nexport default makeSource({\n contentDirPath: \"writings\",\n documentTypes: [Writing],\n mdx: {\n rehypePlugins: [[rehypePrettyCode, rehypeoptions]],\n },\n});\n\n`},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:313,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:313,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:\"Now, you can see the highlighted codes in the blog posts:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:349,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.img,{src:\"https://i.postimg.cc/mrPYKxrm/Screenshot-2023-04-05-at-10-44-36-PM.png\",alt:\"highlighted codes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:351,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:351,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can find more information about \",(0,r.jsxDEV)(n.a,{href:\"https://rehype-pretty-code.netlify.app/\",children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:353,columnNumber:37},this),`\nand `,(0,r.jsxDEV)(n.a,{href:\"https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes\",children:\"Shiki themes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:354,columnNumber:5},this),\".\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:353,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Conclusion\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:356,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"In this tutorial, we have learned how to create a blog using \",(0,r.jsxDEV)(n.code,{children:\"Next.js\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:358,columnNumber:62},this),\", \",(0,r.jsxDEV)(n.code,{children:\"Contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:358,columnNumber:73},this),\", and \",(0,r.jsxDEV)(n.code,{children:\"MDX\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:358,columnNumber:93},this),\". We have learned how to create a blog post, how to list all posts, and how to highlight codes in the blog posts.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:358,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[\"You can find the source code of the \",(0,r.jsxDEV)(n.code,{children:\"Contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:360,columnNumber:37},this),\" blog in the following GitHub repository:\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:360,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:(0,r.jsxDEV)(n.a,{href:\"https://github.com/contentlayerdev/next-contentlayer-example\",children:\"Source code of example\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:362,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:362,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"Resources\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:364,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.ul,{children:[`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://contentlayer.dev/\",children:\"Contentlayer\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:366,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:366,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://nextjs.org/\",children:\"Next.js\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:367,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:367,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://mdxjs.com/\",children:\"MDX\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:368,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:368,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://rehype-pretty-code.netlify.app/\",children:\"rehype-pretty-code\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:369,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:369,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.li,{children:(0,r.jsxDEV)(n.a,{href:\"https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes\",children:\"Shiki themes\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:370,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:370,columnNumber:1},this),`\n`]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:366,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.h2,{children:\"About the author\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:372,columnNumber:1},this),`\n`,(0,r.jsxDEV)(n.p,{children:[(0,r.jsxDEV)(n.a,{href:\"https://arshadd.site\",children:\"Arshad Yaseen\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:374,columnNumber:1},this),\". I'm a software engineer and I love to create aesthetic frontends. If you have any questions, feel free to ask me on \",(0,r.jsxDEV)(n.a,{href:\"https://twitter.com/arshadyaseeen\",children:\"Twitter\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:374,columnNumber:156},this),\".\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:374,columnNumber:1},this)]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\",lineNumber:1,columnNumber:1},this)}function gn(u={}){let{wrapper:n}=u.components||{};return n?(0,r.jsxDEV)(n,Object.assign({},u,{children:(0,r.jsxDEV)(Le,u,void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\"},this)}),void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-d5d38af3-3a8c-4272-ad79-b5ef731a3d7e.mdx\"},this):Le(u)}var xn=gn;return hn(Nn);})();\n/*! Bundled license information:\n\nreact/cjs/react-jsx-dev-runtime.development.js:\n (**\n * @license React\n * react-jsx-dev-runtime.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *)\n*/\n;return Component;" 12 | }, 13 | "_id": "vercel-aws.mdx", 14 | "_raw": { 15 | "sourceFilePath": "vercel-aws.mdx", 16 | "sourceFileName": "vercel-aws.mdx", 17 | "sourceFileDir": ".", 18 | "contentType": "mdx", 19 | "flattenedPath": "vercel-aws" 20 | }, 21 | "type": "Post", 22 | "url": "/posts/vercel-aws" 23 | }, 24 | "documentHash": "1680793292013", 25 | "hasWarnings": false, 26 | "documentTypeName": "Post" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.contentlayer/generated/Post/_index.mjs: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | import nextjsAppdirBlogMdx from './nextjs-appdir-blog.mdx.json' 4 | import vercelAwsMdx from './vercel-aws.mdx.json' 5 | 6 | export const allPosts = [nextjsAppdirBlogMdx, vercelAwsMdx] 7 | -------------------------------------------------------------------------------- /.contentlayer/generated/Post/vercel-aws.mdx.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Powering a serverless Web. Vercel joins AWS Marketplace", 3 | "description": "AWS and Vercel have always had a shared vision. accelerating innovation through the power of serverless computing—and helping customers win big in the process.", 4 | "date": "2023-04-05T18:30:00.000Z", 5 | "author": "Kevin Van Gundy", 6 | "body": { 7 | "raw": "\n![intro image](https://vercel.com/_next/image?url=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Fcontentful%2Fimage%2Fe5382hct74si%2FeV7vmKdeYYQa6CZmDbcHH%2F446d857fb040d725343d487ddcc98b38%2FBlog_Header-V2.png&w=3840&q=75)\n\n#### AWS and Vercel have always had a shared vision: accelerating innovation through the power of serverless computing—and helping customers win big in the process.\n\n#### **Today, I am thrilled to announce that [Vercel is now available on the AWS Marketplace.](https://aws.amazon.com/marketplace/pp/prodview-lwqascgzju3bo) This is a major milestone in our relationship with AWS. Additionally, over the last 12-months, we joined the AWS Partner Network and integrated into the Independent Software Vendor Accelerate Program.**\n\n#### Anyone with an AWS account can now onboard and build on Vercel in just a few clicks. Customers who purchase Vercel through AWS Marketplace have seamless access to Vercel features like:\n\n- [Serverless Functions](https://vercel.com/docs/concepts/functions/serverless-functions) with AWS Lambda\n- [Comments on Preview Deployments](https://vercel.com/blog/introducing-commenting-on-preview-deployments)\n- [Frontend Observability](https://vercel.com/docs/concepts/get-started/monitor)\n- …[and more](https://vercel.com/product-tour?i=0)\n", 8 | "code": "var Component=(()=>{var cr=Object.create;var F=Object.defineProperty;var lr=Object.getOwnPropertyDescriptor;var ur=Object.getOwnPropertyNames;var fr=Object.getPrototypeOf,dr=Object.prototype.hasOwnProperty;var z=(l,a)=>()=>(a||l((a={exports:{}}).exports,a),a.exports),pr=(l,a)=>{for(var v in a)F(l,v,{get:a[v],enumerable:!0})},Ee=(l,a,v,y)=>{if(a&&typeof a==\"object\"||typeof a==\"function\")for(let _ of ur(a))!dr.call(l,_)&&_!==v&&F(l,_,{get:()=>a[_],enumerable:!(y=lr(a,_))||y.enumerable});return l};var mr=(l,a,v)=>(v=l!=null?cr(fr(l)):{},Ee(a||!l||!l.__esModule?F(v,\"default\",{value:l,enumerable:!0}):v,l)),br=l=>Ee(F({},\"__esModule\",{value:!0}),l);var je=z((Er,xe)=>{xe.exports=React});var Re=z(G=>{\"use strict\";(function(){\"use strict\";var l=je(),a=Symbol.for(\"react.element\"),v=Symbol.for(\"react.portal\"),y=Symbol.for(\"react.fragment\"),_=Symbol.for(\"react.strict_mode\"),H=Symbol.for(\"react.profiler\"),K=Symbol.for(\"react.provider\"),X=Symbol.for(\"react.context\"),T=Symbol.for(\"react.forward_ref\"),A=Symbol.for(\"react.suspense\"),L=Symbol.for(\"react.suspense_list\"),N=Symbol.for(\"react.memo\"),U=Symbol.for(\"react.lazy\"),Ne=Symbol.for(\"react.offscreen\"),Z=Symbol.iterator,Se=\"@@iterator\";function ke(e){if(e===null||typeof e!=\"object\")return null;var r=Z&&e[Z]||e[Se];return typeof r==\"function\"?r:null}var x=l.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function p(e){{for(var r=arguments.length,n=new Array(r>1?r-1:0),t=1;t=1&&d>=0&&i[f]!==m[d];)d--;for(;f>=1&&d>=0;f--,d--)if(i[f]!==m[d]){if(f!==1||d!==1)do if(f--,d--,d<0||i[f]!==m[d]){var b=`\n`+i[f].replace(\" at new \",\" at \");return e.displayName&&b.includes(\"\")&&(b=b.replace(\"\",e.displayName)),typeof e==\"function\"&&k.set(e,b),b}while(f>=1&&d>=0);break}}}finally{I=!1,W.current=c,Ie(),Error.prepareStackTrace=s}var R=e?e.displayName||e.name:\"\",ye=R?S(R):\"\";return typeof e==\"function\"&&k.set(e,ye),ye}function Me(e,r,n){return ce(e,!1)}function $e(e){var r=e.prototype;return!!(r&&r.isReactComponent)}function C(e,r,n){if(e==null)return\"\";if(typeof e==\"function\")return ce(e,$e(e));if(typeof e==\"string\")return S(e);switch(e){case A:return S(\"Suspense\");case L:return S(\"SuspenseList\")}if(typeof e==\"object\")switch(e.$$typeof){case T:return Me(e.render);case N:return C(e.type,r,n);case U:{var t=e,s=t._payload,c=t._init;try{return C(c(s),r,n)}catch{}}}return\"\"}var D=Object.prototype.hasOwnProperty,le={},ue=x.ReactDebugCurrentFrame;function O(e){if(e){var r=e._owner,n=C(e.type,e._source,r?r.type:null);ue.setExtraStackFrame(n)}else ue.setExtraStackFrame(null)}function Be(e,r,n,t,s){{var c=Function.call.bind(D);for(var o in e)if(c(e,o)){var i=void 0;try{if(typeof e[o]!=\"function\"){var m=Error((t||\"React class\")+\": \"+n+\" type `\"+o+\"` is invalid; it must be a function, usually from the `prop-types` package, but received `\"+typeof e[o]+\"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.\");throw m.name=\"Invariant Violation\",m}i=e[o](r,o,t,n,null,\"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED\")}catch(f){i=f}i&&!(i instanceof Error)&&(O(s),p(\"%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).\",t||\"React class\",n,o,typeof i),O(null)),i instanceof Error&&!(i.message in le)&&(le[i.message]=!0,O(s),p(\"Failed %s type: %s\",n,i.message),O(null))}}}var qe=Array.isArray;function Y(e){return qe(e)}function ze(e){{var r=typeof Symbol==\"function\"&&Symbol.toStringTag,n=r&&e[Symbol.toStringTag]||e.constructor.name||\"Object\";return n}}function Ge(e){try{return fe(e),!1}catch{return!0}}function fe(e){return\"\"+e}function de(e){if(Ge(e))return p(\"The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.\",ze(e)),fe(e)}var P=x.ReactCurrentOwner,He={key:!0,ref:!0,__self:!0,__source:!0},pe,me,M;M={};function Ke(e){if(D.call(e,\"ref\")){var r=Object.getOwnPropertyDescriptor(e,\"ref\").get;if(r&&r.isReactWarning)return!1}return e.ref!==void 0}function Xe(e){if(D.call(e,\"key\")){var r=Object.getOwnPropertyDescriptor(e,\"key\").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function Ze(e,r){if(typeof e.ref==\"string\"&&P.current&&r&&P.current.stateNode!==r){var n=h(P.current.type);M[n]||(p('Component \"%s\" contains the string ref \"%s\". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref',h(P.current.type),e.ref),M[n]=!0)}}function Je(e,r){{var n=function(){pe||(pe=!0,p(\"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)\",r))};n.isReactWarning=!0,Object.defineProperty(e,\"key\",{get:n,configurable:!0})}}function Qe(e,r){{var n=function(){me||(me=!0,p(\"%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)\",r))};n.isReactWarning=!0,Object.defineProperty(e,\"ref\",{get:n,configurable:!0})}}var er=function(e,r,n,t,s,c,o){var i={$$typeof:a,type:e,key:r,ref:n,props:o,_owner:c};return i._store={},Object.defineProperty(i._store,\"validated\",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(i,\"_self\",{configurable:!1,enumerable:!1,writable:!1,value:t}),Object.defineProperty(i,\"_source\",{configurable:!1,enumerable:!1,writable:!1,value:s}),Object.freeze&&(Object.freeze(i.props),Object.freeze(i)),i};function rr(e,r,n,t,s){{var c,o={},i=null,m=null;n!==void 0&&(de(n),i=\"\"+n),Xe(r)&&(de(r.key),i=\"\"+r.key),Ke(r)&&(m=r.ref,Ze(r,s));for(c in r)D.call(r,c)&&!He.hasOwnProperty(c)&&(o[c]=r[c]);if(e&&e.defaultProps){var f=e.defaultProps;for(c in f)o[c]===void 0&&(o[c]=f[c])}if(i||m){var d=typeof e==\"function\"?e.displayName||e.name||\"Unknown\":e;i&&Je(o,d),m&&Qe(o,d)}return er(e,i,m,s,t,P.current,o)}}var $=x.ReactCurrentOwner,be=x.ReactDebugCurrentFrame;function j(e){if(e){var r=e._owner,n=C(e.type,e._source,r?r.type:null);be.setExtraStackFrame(n)}else be.setExtraStackFrame(null)}var B;B=!1;function q(e){return typeof e==\"object\"&&e!==null&&e.$$typeof===a}function ve(){{if($.current){var e=h($.current.type);if(e)return`\n\nCheck the render method of \\``+e+\"`.\"}return\"\"}}function nr(e){{if(e!==void 0){var r=e.fileName.replace(/^.*[\\\\\\/]/,\"\"),n=e.lineNumber;return`\n\nCheck your code at `+r+\":\"+n+\".\"}return\"\"}}var he={};function tr(e){{var r=ve();if(!r){var n=typeof e==\"string\"?e:e.displayName||e.name;n&&(r=`\n\nCheck the top-level render call using <`+n+\">.\")}return r}}function ge(e,r){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var n=tr(r);if(he[n])return;he[n]=!0;var t=\"\";e&&e._owner&&e._owner!==$.current&&(t=\" It was passed a child from \"+h(e._owner.type)+\".\"),j(e),p('Each child in a list should have a unique \"key\" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',n,t),j(null)}}function _e(e,r){{if(typeof e!=\"object\")return;if(Y(e))for(var n=0;n\",i=\" Did you accidentally export a JSX literal instead of a component?\"):f=typeof e,p(\"React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s\",f,i)}var d=rr(e,r,n,s,c);if(d==null)return d;if(o){var b=r.children;if(b!==void 0)if(t)if(Y(b)){for(var R=0;R{\"use strict\";we.exports=Re()});var _r={};pr(_r,{default:()=>gr,frontmatter:()=>vr});var u=mr(Pe()),vr={title:\"Powering a serverless Web. Vercel joins AWS Marketplace\",description:\"AWS and Vercel have always had a shared vision. accelerating innovation through the power of serverless computing\\u2014and helping customers win big in the process.\",date:\"2023-4-6\",author:\"Kevin Van Gundy\"};function Te(l){let a=Object.assign({p:\"p\",img:\"img\",h4:\"h4\",strong:\"strong\",a:\"a\",ul:\"ul\",li:\"li\"},l.components);return(0,u.jsxDEV)(u.Fragment,{children:[(0,u.jsxDEV)(a.p,{children:(0,u.jsxDEV)(a.img,{src:\"https://vercel.com/_next/image?url=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Fcontentful%2Fimage%2Fe5382hct74si%2FeV7vmKdeYYQa6CZmDbcHH%2F446d857fb040d725343d487ddcc98b38%2FBlog_Header-V2.png&w=3840&q=75\",alt:\"intro image\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:8,columnNumber:1},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:8,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.h4,{children:\"AWS and Vercel have always had a shared vision: accelerating innovation through the power of serverless computing\\u2014and helping customers win big in the process.\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:10,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.h4,{children:(0,u.jsxDEV)(a.strong,{children:[\"Today, I am thrilled to announce that \",(0,u.jsxDEV)(a.a,{href:\"https://aws.amazon.com/marketplace/pp/prodview-lwqascgzju3bo\",children:\"Vercel is now available on the AWS Marketplace.\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:12,columnNumber:46},this),\" This is a major milestone in our relationship with AWS. Additionally, over the last 12-months, we joined the AWS Partner Network and integrated into the Independent Software Vendor Accelerate Program.\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:12,columnNumber:6},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:12,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.h4,{children:\"Anyone with an AWS account can now onboard and build on Vercel in just a few clicks. Customers who purchase Vercel through AWS Marketplace have seamless access to Vercel features like:\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:14,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.ul,{children:[`\n`,(0,u.jsxDEV)(a.li,{children:[(0,u.jsxDEV)(a.a,{href:\"https://vercel.com/docs/concepts/functions/serverless-functions\",children:\"Serverless Functions\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:16,columnNumber:3},this),\" with AWS Lambda\"]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:16,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.li,{children:(0,u.jsxDEV)(a.a,{href:\"https://vercel.com/blog/introducing-commenting-on-preview-deployments\",children:\"Comments on Preview Deployments\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:17,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:17,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.li,{children:(0,u.jsxDEV)(a.a,{href:\"https://vercel.com/docs/concepts/get-started/monitor\",children:\"Frontend Observability\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:18,columnNumber:3},this)},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:18,columnNumber:1},this),`\n`,(0,u.jsxDEV)(a.li,{children:[\"\\u2026\",(0,u.jsxDEV)(a.a,{href:\"https://vercel.com/product-tour?i=0\",children:\"and more\"},void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:19,columnNumber:4},this)]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:19,columnNumber:1},this),`\n`]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:16,columnNumber:1},this)]},void 0,!0,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\",lineNumber:1,columnNumber:1},this)}function hr(l={}){let{wrapper:a}=l.components||{};return a?(0,u.jsxDEV)(a,Object.assign({},l,{children:(0,u.jsxDEV)(Te,l,void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\"},this)}),void 0,!1,{fileName:\"/Users/arshadyaseen/Desktop/Learning Projects/nextjs-appdir-blog/posts/_mdx_bundler_entry_point-42ac442c-41b5-4b5d-8958-c97c76ad198f.mdx\"},this):Te(l)}var gr=hr;return br(_r);})();\n/*! Bundled license information:\n\nreact/cjs/react-jsx-dev-runtime.development.js:\n (**\n * @license React\n * react-jsx-dev-runtime.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *)\n*/\n;return Component;" 9 | }, 10 | "_id": "vercel-aws.mdx", 11 | "_raw": { 12 | "sourceFilePath": "vercel-aws.mdx", 13 | "sourceFileName": "vercel-aws.mdx", 14 | "sourceFileDir": ".", 15 | "contentType": "mdx", 16 | "flattenedPath": "vercel-aws" 17 | }, 18 | "type": "Post", 19 | "url": "/posts/vercel-aws" 20 | } -------------------------------------------------------------------------------- /.contentlayer/generated/index.d.ts: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | import { Post, DocumentTypes, DataExports } from './types' 4 | import { SourceProvideSchemaErrorJSON, SourceFetchDataErrorJSON } from 'contentlayer/core' 5 | 6 | export * from './types' 7 | 8 | export declare const allPosts: Post[] 9 | 10 | export declare const allDocuments: DocumentTypes[] 11 | 12 | 13 | -------------------------------------------------------------------------------- /.contentlayer/generated/index.mjs: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | export { isType } from 'contentlayer/client' 4 | 5 | // NOTE During development Contentlayer imports from `.mjs` files to improve HMR speeds. 6 | // During (production) builds Contentlayer it imports from `.json` files to improve build performance. 7 | import { allPosts } from './Post/_index.mjs' 8 | 9 | export { allPosts } 10 | 11 | export const allDocuments = [...allPosts] 12 | 13 | 14 | -------------------------------------------------------------------------------- /.contentlayer/generated/types.d.ts: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | import type { Markdown, MDX, ImageFieldData, IsoDateTimeString } from 'contentlayer/core' 4 | import * as Local from 'contentlayer/source-files' 5 | 6 | export { isType } from 'contentlayer/client' 7 | 8 | export type { Markdown, MDX, ImageFieldData, IsoDateTimeString } 9 | 10 | /** Document types */ 11 | export type Post = { 12 | /** File path relative to `contentDirPath` */ 13 | _id: string 14 | _raw: Local.RawDocumentData 15 | type: 'Post' 16 | /** The title of the post */ 17 | title: string 18 | /** The description of the post */ 19 | description: string 20 | /** The date of the post */ 21 | date: IsoDateTimeString 22 | /** The author of the post */ 23 | author: string 24 | /** MDX file body */ 25 | body: MDX 26 | url: string 27 | } 28 | 29 | /** Nested types */ 30 | 31 | 32 | /** Helper types */ 33 | 34 | export type AllTypes = DocumentTypes | NestedTypes 35 | export type AllTypeNames = DocumentTypeNames | NestedTypeNames 36 | 37 | export type DocumentTypes = Post 38 | export type DocumentTypeNames = 'Post' 39 | 40 | export type NestedTypes = never 41 | export type NestedTypeNames = never 42 | 43 | export type DataExports = { 44 | allDocuments: DocumentTypes[] 45 | allPosts: Post[] 46 | } 47 | 48 | 49 | export interface ContentlayerGenTypes { 50 | documentTypes: DocumentTypes 51 | documentTypeMap: DocumentTypeMap 52 | documentTypeNames: DocumentTypeNames 53 | nestedTypes: NestedTypes 54 | nestedTypeMap: NestedTypeMap 55 | nestedTypeNames: NestedTypeNames 56 | allTypeNames: AllTypeNames 57 | dataExports: DataExports 58 | } 59 | 60 | declare global { 61 | interface ContentlayerGen extends ContentlayerGenTypes {} 62 | } 63 | 64 | export type DocumentTypeMap = { 65 | Post: Post 66 | } 67 | 68 | export type NestedTypeMap = { 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /.contentlayer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dot-contentlayer", 3 | "description": "This package is auto-generated by Contentlayer", 4 | "version": "0.0.0-2QRL2QTS", 5 | "exports": { 6 | "./generated": { 7 | "import": "./generated/index.mjs" 8 | } 9 | }, 10 | "typesVersions": { 11 | "*": { 12 | "generated": [ 13 | "./generated" 14 | ] 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | #vs code 39 | .vscode 40 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Contentlayer + [Next.js 13 Blog](https://nextjs-appdir-blog.vercel.app) 2 | 3 | Welcome to the Contentlayer + Next.js 13 Blog, a blog app built with Next.js 13 app folder and Contentlayer. It serves as an excellent example of how to use Next.js 13 app folder and Contentlayer together. 4 | 5 | [![Next.js 13 appDir blog](./public/og-image.png)](https://www.nextjs-appdir-blog.vercel.app) 6 | 7 | ## How it works 8 | 9 | This project utilizes the Contentlayer content manager and the experimental app of Next.js 13. The latest version of Next.js brings new features like appDir, metadata API, and more. Contentlayer simplifies content management and enhances the developer experience of modern web frameworks, especially in Next.js projects. With these powerful tools, you can create an incredible blog in a new and exciting way. 10 | 11 | If you want to know more about how this project was built, please check out the corresponding [blog post](https://arshadd.site/writing/nextjs-appdir-blog). 12 | 13 | And if you want to try it out for yourself, simply clone this example project. 14 | 15 | ## Running Locally 16 | 17 | To run the application locally, open your terminal and execute the following command. After that, it will be available at `http://localhost:3000`. 18 | 19 | 20 | ## One-Click Deploy 21 | 22 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=vercel-examples) by clicking on the button below. 23 | 24 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/arshad-yaseen/nextjs-appdir-blog&project-name=nextjs-appdir-blog&repo-name=nextjs-appdir-blog) 25 | -------------------------------------------------------------------------------- /app/api/hello/route.ts: -------------------------------------------------------------------------------- 1 | export async function GET(request: Request) { 2 | return new Response('Hello, Next.js!') 3 | } 4 | -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | 6 | pre { 7 | padding: 15px 20px; 8 | border-radius: 10px; 9 | background-color: #f9f8f9; 10 | overflow: auto; 11 | font-size: 0.9rem; 12 | margin: 40px 0; 13 | max-width: 80vw; 14 | } 15 | article p { 16 | font-size: 1rem; 17 | line-height: 1.8rem; 18 | margin-top: 20px; 19 | } 20 | article h1 { 21 | font-size: 2.5rem; 22 | line-height: 3.5rem; 23 | margin-top: 60px; 24 | font-weight: 525; 25 | } 26 | article h2 { 27 | font-size: 2rem; 28 | line-height: 3rem; 29 | margin-top: 60px; 30 | font-weight: 425; 31 | } 32 | article h3 { 33 | font-size: 1.4rem; 34 | line-height: 2.5rem; 35 | margin-top: 50px; 36 | font-weight: 425; 37 | } 38 | article h4 { 39 | font-size: 1.2rem; 40 | line-height: 2rem; 41 | margin-top: 30px; 42 | font-weight: 425; 43 | } 44 | article h5 { 45 | font-size: 1rem; 46 | line-height: 1.5rem; 47 | margin-top: 30px; 48 | line-height: 1.6rem; 49 | font-weight: 350; 50 | } 51 | article h6 { 52 | font-size: 0.9rem; 53 | line-height: 1.3rem; 54 | margin-top: 30px; 55 | } 56 | article ul { 57 | list-style: disc; 58 | padding-left: 1.5rem; 59 | margin-top: 50px; 60 | } 61 | article ol { 62 | list-style: decimal; 63 | padding-left: 1.5rem; 64 | margin-top: 20px; 65 | } 66 | article li { 67 | font-size: 1.1rem; 68 | line-height: 1.3rem; 69 | margin-top: 20px; 70 | } 71 | article a { 72 | transition: 0.2s ease; 73 | color: #0170F2; 74 | font-size: 1.1rem; 75 | } 76 | article a:hover { 77 | border-bottom: #0170F2 1px solid; 78 | } 79 | 80 | article code { 81 | background-color: #F3F3F3; 82 | padding: 2px 7px; 83 | border-radius: 5px; 84 | font-size: 0.9rem; 85 | border: 1px solid #E9E8E9; 86 | } 87 | article pre code { 88 | background-color: transparent; 89 | padding: 0; 90 | border-radius: 0px; 91 | font-size: auto; 92 | border: none; 93 | } 94 | article { 95 | font-size: 1.1rem; 96 | line-height: 1.8rem; 97 | margin-top: 20px; 98 | color: #171616; 99 | } 100 | *::selection{ 101 | background-color: #E9E9E8; 102 | } 103 | 104 | article img { 105 | max-width: 100%; 106 | margin-top: 50px; 107 | margin-bottom: 50px; 108 | box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.014); 109 | border-radius: 20px; 110 | border: 1px solid #E9E8E9; 111 | } -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from "next"; 2 | import "./globals.css"; 3 | 4 | export const metadata: Metadata = { 5 | title: "Next.js App Dir Blog", 6 | description: 7 | "This is a blog app built with Next.js 13 app folder and Contentlayer. It is a great example of how to use Next.js 13 app folder and Contentlayer together.", 8 | icons: { 9 | icon: [ 10 | { 11 | url: "/favicon.ico", 12 | sizes: "32x32", 13 | }, 14 | { 15 | url: "/favicon.ico", 16 | sizes: "16x16", 17 | }, 18 | { 19 | url: "/favicon.ico", 20 | sizes: "64x64", 21 | }, 22 | ], 23 | }, 24 | twitter: { 25 | card: "summary_large_image", 26 | title: "Next.js App Dir Blog", 27 | description: 28 | "This is a blog app built with Next.js 13 app folder and Contentlayer. It is a great example of how to use Next.js 13 app folder and Contentlayer together.", 29 | siteId: "Next.js App Dir Blog", 30 | creator: "@arshadyaseeen", 31 | images: ["/og-image.png"], 32 | }, 33 | openGraph: { 34 | title: "Next.js App Dir Blog", 35 | description: 36 | "This is a blog app built with Next.js 13 app folder and Contentlayer. It is a great example of how to use Next.js 13 app folder and Contentlayer together.", 37 | type: "website", 38 | url: "https://nextjs-appdir-blog.vercel.app", 39 | images: [ 40 | { 41 | url: "/og-image.png", 42 | width: 1200, 43 | height: 720, 44 | type: "image/jpeg", 45 | }, 46 | ], 47 | }, 48 | }; 49 | 50 | export default function RootLayout({ 51 | children, 52 | }: { 53 | children: React.ReactNode; 54 | }) { 55 | return ( 56 | 57 | {children} 58 | 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /app/page.module.css: -------------------------------------------------------------------------------- 1 | .main { 2 | display: flex; 3 | justify-content: center; 4 | height: 100vh; 5 | width: 100%; 6 | } 7 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | import Header from "@/components/Header"; 2 | import styles from "./page.module.css"; 3 | import Link from "next/link"; 4 | import { BsArrowRightShort } from "react-icons/bs"; 5 | import { AiFillGithub } from "react-icons/ai"; 6 | import Footer from "@/components/Footer"; 7 | 8 | export default function Home() { 9 | return ( 10 |
11 |
12 |
13 | 14 |
15 |
16 | 20 |
21 | Star on GitHub 22 |
23 | 24 |
25 |
26 |

27 | Next.js 13 new appDir
Blog with Contentlayer 28 |

29 |

30 | This is a blog app built with Next.js 13 app folder and 31 | Contentlayer. It is a great example of how to use Next.js 13 app 32 | folder and Contentlayer together. 33 |

34 | 37 |
38 | Go to Blogs 39 |
40 | 41 | How built this? 42 |
43 |
44 | 45 |
46 |
47 |
48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /app/posts/[slug]/page.tsx: -------------------------------------------------------------------------------- 1 | import Header from "@/components/Header"; 2 | import PostNotFound from "@/components/PostNotFound"; 3 | import MDXComponents from "@/utils/mdxcomponents"; 4 | import { Post, allPosts } from "contentlayer/generated"; 5 | import { format, parseISO } from "date-fns"; 6 | import { Metadata } from "next"; 7 | import { getMDXComponent } from "next-contentlayer/hooks"; 8 | 9 | type Props = { 10 | params: { slug: string }; 11 | searchParams: { [key: string]: string | string[] | undefined }; 12 | }; 13 | 14 | export const generateStaticParams = async () => 15 | allPosts.map((post: Post) => ({ slug: post._raw.flattenedPath })); 16 | 17 | export const generateMetadata = ({ params }: Props): Metadata => { 18 | const post = allPosts.find( 19 | (post: Post) => post._raw.flattenedPath === params.slug 20 | ); 21 | return { title: post?.title, description: post?.description }; 22 | }; 23 | 24 | const PostLayout = ({ params }: { params: { slug: string } }) => { 25 | const post = allPosts.find( 26 | (post: Post) => post._raw.flattenedPath === params.slug 27 | ); 28 | 29 | let MDXContent; 30 | 31 | if (!post) { 32 | return ; 33 | } else { 34 | MDXContent = getMDXComponent(post!.body.code); 35 | } 36 | 37 | return ( 38 |
39 |
40 |
41 |
42 |

43 | {format(parseISO(post.date), "LLLL d, yyyy")} 44 |

45 |

46 | {post.title} 47 |

48 |
49 | 50 |
51 |
52 |
53 |
54 | ); 55 | }; 56 | 57 | export default PostLayout; 58 | -------------------------------------------------------------------------------- /app/posts/page.tsx: -------------------------------------------------------------------------------- 1 | import Header from "@/components/Header"; 2 | import React from "react"; 3 | import { allPosts, Post } from "contentlayer/generated"; 4 | import { compareDesc, format, parseISO } from "date-fns"; 5 | import Link from "next/link"; 6 | import { Metadata } from "next"; 7 | 8 | export const metadata: Metadata = { 9 | title: "Blogs - Next.js App Dir Blog", 10 | }; 11 | 12 | function PostCard(post: Post) { 13 | return ( 14 | 18 |

19 | {format(parseISO(post.date), "LLLL d, yyyy")} • {post.author} 20 |

21 |

22 | {post.title} 23 |

24 | 25 | ); 26 | } 27 | 28 | function page() { 29 | const posts = allPosts.sort((a, b) => 30 | compareDesc(new Date(a.date), new Date(b.date)) 31 | ); 32 | 33 | return ( 34 |
35 |
36 |
37 | 38 |
39 | {posts.map((post, idx) => ( 40 | 41 | ))} 42 |
43 |
44 |
45 | ); 46 | } 47 | 48 | export default page; 49 | -------------------------------------------------------------------------------- /components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import React from "react"; 3 | import { AiOutlineTwitter, AiFillGithub } from "react-icons/ai"; 4 | 5 | function Footer() { 6 | return ( 7 |
8 |
9 |

10 | Powered by{" "} 11 | Contentlayer and{" "} 12 | Vercel 13 |

14 |
15 |
16 | 17 | 18 |
19 |
20 | ); 21 | } 22 | 23 | export default Footer; 24 | -------------------------------------------------------------------------------- /components/Header.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | import Link from "next/link"; 3 | import React from "react"; 4 | 5 | function Header() { 6 | return ( 7 |
8 | 12 | next.js svg 20 |

BLOG

21 | 22 | 27 | vercel svg 35 | 36 |
37 | ); 38 | } 39 | 40 | export default Header; 41 | -------------------------------------------------------------------------------- /components/PostNotFound.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "./Header"; 3 | import Link from "next/link"; 4 | import { BsArrowLeftShort } from "react-icons/bs"; 5 | 6 | function PostNotFound() { 7 | return ( 8 |
9 |
10 |
11 |
12 |

Post not found

13 | 14 |
15 | Go to Blogs 16 |
17 | 18 |
19 |
20 |
21 | ); 22 | } 23 | 24 | export default PostNotFound; 25 | -------------------------------------------------------------------------------- /contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from "contentlayer/source-files"; 2 | import rehypePrettyCode from "rehype-pretty-code"; 3 | import { rehypeoptions } from "./utils/rehypeoptions"; 4 | 5 | const Post = defineDocumentType(() => ({ 6 | name: "Post", 7 | filePathPattern: `**/*.mdx`, 8 | contentType: "mdx", 9 | fields: { 10 | title: { 11 | type: "string", 12 | description: "The title of the post", 13 | required: true, 14 | }, 15 | description: { 16 | type: "string", 17 | description: "The description of the post", 18 | required: true, 19 | }, 20 | date: { 21 | type: "date", 22 | description: "The date of the post", 23 | required: true, 24 | }, 25 | author: { 26 | type: "string", 27 | description: "The author of the post", 28 | required: true, 29 | }, 30 | }, 31 | computedFields: { 32 | url: { 33 | type: "string", 34 | resolve: (doc) => `/posts/${doc._raw.flattenedPath}`, 35 | }, 36 | }, 37 | })); 38 | 39 | export default makeSource({ 40 | contentDirPath: "posts", 41 | documentTypes: [Post], 42 | mdx: { 43 | rehypePlugins: [[rehypePrettyCode, rehypeoptions]], 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const { withContentlayer } = require('next-contentlayer') 3 | 4 | module.exports = withContentlayer({ 5 | experimental: { appDir: true }, 6 | }) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-appdir-blog", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@opentelemetry/api": "^1.4.1", 13 | "@types/node": "18.15.11", 14 | "@types/react": "18.0.33", 15 | "@types/react-dom": "18.0.11", 16 | "contentlayer": "^0.3.1", 17 | "date-fns": "^2.29.3", 18 | "eslint": "8.37.0", 19 | "eslint-config-next": "13.2.4", 20 | "next": "13.2.4", 21 | "next-contentlayer": "^0.3.1", 22 | "react": "18.2.0", 23 | "react-dom": "18.2.0", 24 | "react-icons": "^4.8.0", 25 | "rehype-pretty-code": "^0.9.4", 26 | "shiki": "^0.14.1", 27 | "typescript": "5.0.3" 28 | }, 29 | "devDependencies": { 30 | "autoprefixer": "^10.4.14", 31 | "postcss": "^8.4.21", 32 | "tailwindcss": "^3.3.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /posts/nextjs-appdir-blog.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Build a blog app with new Next.js 13 app folder and Contentlayer 3 | description: Learn how to build a blog app with Next.js 13 app folder and Contentlayer 4 | date: 2023-4-5 5 | author: Arshad Yaseen 6 | --- 7 | 8 | ![intro image](https://i.postimg.cc/sX7F0kRS/Screenshot-2023-04-06-at-11-16-12-PM.png) 9 | 10 | ### Contents 11 | 12 | - Create a Next.js app 13 | - Create a blog page with [contentlayer](https://contentlayer.dev) 14 | - Styling the blog 15 | - Custom components 16 | - List all posts 17 | - Highlight codes 18 | 19 | ### Let's get started! 20 | 21 | First, we need to create a new Next.js app with the new app folder feature: 22 | 23 | ```bash 24 | npx create-next-app@latest --ts --experimental-app 25 | ``` 26 | 27 | You can also use `Javascript` instead of `Typescript`. In this tutorial we will use `Typescript`. 28 | 29 | Then, you need to install the Contentlayer: 30 | 31 | ```bash 32 | npm i contentlayer next-contentlayer @opentelemetry/api 33 | ``` 34 | 35 | Now, export the `contentlayer` config in the `next.config.js`: 36 | 37 | ```js 38 | const { withContentlayer } = require("next-contentlayer"); 39 | 40 | module.exports = withContentlayer({ 41 | experimental: { appDir: true }, 42 | }); 43 | ``` 44 | 45 | Now, we need to create a `contentlayer.config.ts` file in the root of the project and add the following code: 46 | 47 | ```ts 48 | import { defineDocumentType, makeSource } from "contentlayer/source-files"; 49 | 50 | const Post = defineDocumentType(() => ({ 51 | name: "Post", 52 | filePathPattern: `**/*.mdx`, 53 | contentType: "mdx", 54 | fields: { 55 | title: { 56 | type: "string", 57 | description: "The title of the post", 58 | required: true, 59 | }, 60 | date: { 61 | type: "date", 62 | description: "The date of the post", 63 | required: true, 64 | }, 65 | }, 66 | computedFields: { 67 | url: { 68 | type: "string", 69 | resolve: (doc) => `/posts/${doc._raw.flattenedPath}`, 70 | }, 71 | }, 72 | })); 73 | 74 | export default makeSource({ 75 | contentDirPath: "posts", 76 | documentTypes: [Post], 77 | }); 78 | ``` 79 | 80 | Above code is the config for the Contentlayer. It will create a `Post` document type and will generate the `url` field based on the `flattenedPath` field. 81 | 82 | You can add more document types and fields such as `Author` and `Category` and more. 83 | 84 | Now, we need to create a `posts` folder in the root of the project and create a `hello-world.mdx` file in it and add the following code: 85 | 86 | You can name the file whatever you want. In this tutorial, we will use `hello-world.mdx`: 87 | 88 | ```mdx 89 | --- 90 | title: How to create Next.js app 91 | date: 2023-04-06 92 | --- 93 | 94 | # Install Next.js 95 | 96 | ### Fist you need to install Next.js with the following command: 97 | 98 | npm i create-next-app@latest 99 | ``` 100 | 101 | Above code is the `mdx` file. You can use `md` instead of `mdx`. You can add more fields such as `description` and `author` and more. 102 | 103 | Then, restart the app with the following command: 104 | 105 | ```bash 106 | npm run dev 107 | ``` 108 | 109 | Now, you can see new `.contentlayer` folder in the root of the project. This folder contains the generated JSON files, types and more. 110 | 111 | ![generate contentlayer folder](https://i.postimg.cc/nrdVwTLt/Screenshot-2023-04-05-at-6-13-25-PM.png) 112 | 113 | We need to install `date-fns` for sorting posts by date and format the date: 114 | 115 | ```bash 116 | npm i date-fns 117 | ``` 118 | 119 | And we need to add the following code in the `tsconfig.json` file: 120 | 121 | ```ts 122 | "paths": { 123 | "@/*": ["./*"], 124 | "contentlayer/generated": ["./.contentlayer/generated"] 125 | } 126 | ``` 127 | 128 | Above code is for importing the generated files from the `.contentlayer` folder. 129 | 130 | Now, we need to create a `posts` folder in the `app` folder and create a `[slug]` folder in it. and create a `page.tsx` file in `[slug]` folder and add the following code: 131 | 132 | `app/posts/[slug]/page.tsx` 133 | 134 | ```tsx 135 | import { Post, allPosts } from "contentlayer/generated"; 136 | import { getMDXComponent } from "next-contentlayer/hooks"; 137 | import { format, parseISO } from "date-fns"; 138 | import { Metadata } from "next"; 139 | 140 | type Props = { 141 | params: { slug: string }; 142 | searchParams: { [key: string]: string | string[] | undefined }; 143 | }; 144 | 145 | export const generateStaticParams = async () => 146 | allPosts.map((post:Post) => ({ slug: post._raw.flattenedPath })); 147 | export const generateMetadata = ({ params }: Props): Metadata => { 148 | const post = allPosts.find( 149 | (post: Post) => post._raw.flattenedPath === params.slug: any 150 | ); 151 | return { title: post?.title, description: post?.description }; 152 | }; 153 | 154 | const PostLayout = ({ params }: { params: { slug: string } }) => { 155 | const post = allPosts.find((post: Post) => post._raw.flattenedPath === params.slug); 156 | 157 | let MDXContent; 158 | 159 | if (!post) { 160 | return
404
; 161 | } else { 162 | MDXContent = getMDXComponent(post!.body.code); 163 | } 164 | 165 | return ( 166 |
167 |

{post.title}

168 |

{format(parseISO(post.date), "LLLL d, yyyy")}

169 |
170 | 171 |
172 |
173 | ); 174 | }; 175 | 176 | export default PostLayout; 177 | ``` 178 | 179 | Above code is the page for the blog post. It will render the blog post based on the `slug` parameter. 180 | 181 | Now, you can see the blog rendered in the `http://localhost:3000/posts/hello-world`: 182 | 183 | ![blog rendered](https://i.postimg.cc/vHZ5HHC0/Screenshot-2023-04-05-at-6-34-14-PM.png) 184 | 185 | ## Styling the blog 186 | 187 | Now, we need to style the blog using `CSS` or others. In this tutorial, we will use `CSS`: 188 | 189 | `globals.css` 190 | 191 | ```css 192 | pre { 193 | padding: 15px 20px; 194 | border-radius: 10px; 195 | background-color: #f9f8f981; 196 | overflow: auto; 197 | font-size: 0.9rem; 198 | margin: 40px 0; 199 | } 200 | article p { 201 | font-size: 1rem; 202 | line-height: 1.8rem; 203 | margin-top: 20px; 204 | } 205 | article h1 { 206 | font-size: 2.5rem; 207 | line-height: 3.5rem; 208 | margin-top: 60px; 209 | font-weight: 425; 210 | } 211 | 212 | ... 213 | ``` 214 | 215 | Get full example css code from [here](https://github.com/arshad-yaseen/portfolio/blob/main/app/globals.css) 216 | 217 | Now, you can see the blog styled: 218 | 219 | ![styled blog](https://i.postimg.cc/0jr5kM57/Screenshot-2023-04-05-at-8-43-24-PM.png) 220 | 221 | Also you can use `TailwindCSS` or others. 222 | 223 | ## Custom components 224 | 225 | Custom components is a great feature of `MDX`. You can create your own components and use them in your blog posts. 226 | 227 | For example, we can create a `CodeSnippet` component: 228 | 229 | `app/posts/[slug]/page.tsx` 230 | 231 | ```tsx 232 | import { allPosts } from "contentlayer/generated"; 233 | import { getMDXComponent } from "next-contentlayer/hooks"; 234 | import { format, parseISO } from "date-fns"; 235 | import { Snippet } from "@geist-ui/core"; 236 | 237 | ... 238 | 239 | const CodeSnippet = (props: any) => ( 240 | 241 | ); 242 | 243 | return ( 244 |
245 |

246 | {post.title} 247 |

248 |

{format(parseISO(post.date), "LLLL d, yyyy")}

249 |
250 | 251 |
252 |
253 | ); 254 | 255 | export default PostLayout; 256 | ``` 257 | 258 | Now, you can use the `CodeSnippet` component in your blog posts: 259 | 260 | ```mdx 261 | --- 262 | title: How to create a Next.js app 263 | date: 2023-04-06 264 | --- 265 | 266 | # Install Next.js 267 | 268 | ### First, install Next.js using the following command: 269 | 270 | 271 | ``` 272 | 273 | Now, you can see the `CodeSnippet` component in the blog post: 274 | 275 | ![code snippet](https://i.postimg.cc/MT7756nQ/Screenshot-2023-04-05-at-9-33-21-PM.png) 276 | 277 | ## List all posts 278 | 279 | Now, we need to create a page that lists all posts. For this, we need to create a `posts` folder in the `app` folder and create a `page.tsx` file in it and add the following code: 280 | 281 | `app/posts/page.tsx` 282 | 283 | ```tsx 284 | import Link from "next/link"; 285 | import { allPosts, Post } from "contentlayer/generated"; 286 | import { compareDesc } from "date-fns"; 287 | 288 | function PostCard(post: Post) { 289 | return ( 290 |
291 |

292 | 293 | {post.title} 294 | 295 |

296 |

{post.description}

297 |
298 | ); 299 | } 300 | 301 | function page() { 302 | const posts = allPosts.sort((a, b) => 303 | compareDesc(new Date(a.date), new Date(b.date)) 304 | ); 305 | 306 | return ( 307 |
308 |
309 | {posts.map((post, idx) => ( 310 | 311 | ))} 312 |
313 |
314 | ); 315 | } 316 | 317 | export default page; 318 | ``` 319 | 320 | Now, you can see the list of all posts in the `http://localhost:3000/posts`: 321 | 322 | ![list of all posts](https://i.postimg.cc/LsRQMbjL/Screenshot-2023-04-05-at-10-23-37-PM.png) 323 | 324 | ## Highlight codes 325 | 326 | Now, we need to highlight the codes in the blog posts. For this, we will use `rehype-pretty-code`: 327 | 328 | ```bash 329 | npm i rehype-pretty-code shiki 330 | ``` 331 | 332 | Now, we need to add the `rehype-pretty-code` plugin to the `contentlayer.config.ts` file: 333 | 334 | `contentlayer.config.ts` 335 | 336 | ```ts 337 | import { defineDocumentType, makeSource } from "contentlayer/source-files"; 338 | import rehypePrettyCode from "rehype-pretty-code"; 339 | 340 | const Post = defineDocumentType(() => ({ 341 | ... 342 | })); 343 | 344 | const rehypeoptions = { 345 | // Use one of Shiki's packaged themes 346 | theme: "light-plus", 347 | // Set to true to keep the background color 348 | keepBackground: true , 349 | onVisitLine(node: any) { 350 | if (node.children.length === 0) { 351 | node.children = [{ type: "text", value: " " }]; 352 | } 353 | }, 354 | onVisitHighlightedLine(node: any) { 355 | node.properties.className.push("highlighted"); 356 | }, 357 | onVisitHighlightedWord(node: any, id: any) { 358 | node.properties.className = ["word"]; 359 | }, 360 | }; 361 | 362 | export default makeSource({ 363 | contentDirPath: "posts", 364 | documentTypes: [Post], 365 | mdx: { 366 | rehypePlugins: [[rehypePrettyCode, rehypeoptions]], 367 | }, 368 | }); 369 | 370 | ``` 371 | 372 | Now, you can see the highlighted codes in the blog posts: 373 | 374 | ![highlighted codes](https://i.postimg.cc/mrPYKxrm/Screenshot-2023-04-05-at-10-44-36-PM.png) 375 | 376 | You can find more information about [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) 377 | and [Shiki themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes). 378 | 379 | Finally you can start building your blog with `Contentlayer` and `Next.js`. The great feature of `Contentlayer` is that Contentlayer will automatically save and refresh the blog when you add a new blog post or edit an existing blog post. 380 | 381 | 382 | ## Conclusion 383 | 384 | In this tutorial, we have learned how to create a blog using `Next.js`, `Contentlayer`, and `MDX`. We have learned how to create a blog post, how to list all posts, and how to highlight codes in the blog posts. 385 | 386 | You can find the source code of the `Contentlayer` blog in the following GitHub repository: 387 | 388 | [Source code of example](https://github.com/arshad-yaseen/nextjs-appdir-blog) 389 | 390 | ## Resources 391 | 392 | - [Contentlayer](https://contentlayer.dev/) 393 | - [Next.js](https://nextjs.org/) 394 | - [MDX](https://mdxjs.com/) 395 | - [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) 396 | - [Shiki themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes) 397 | 398 | ## About the author 399 | 400 | [Arshad Yaseen](https://arshadd.site). I'm a software engineer and I love to create aesthetic frontends. If you have any questions, feel free to ask me on [Twitter](https://twitter.com/arshadyaseeen). -------------------------------------------------------------------------------- /posts/vercel-aws.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Powering a serverless Web. Vercel joins AWS Marketplace 3 | description: AWS and Vercel have always had a shared vision. accelerating innovation through the power of serverless computing—and helping customers win big in the process. 4 | date: 2023-4-6 5 | author: Kevin Van Gundy 6 | --- 7 | 8 | ![intro image](https://vercel.com/_next/image?url=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Fcontentful%2Fimage%2Fe5382hct74si%2FeV7vmKdeYYQa6CZmDbcHH%2F446d857fb040d725343d487ddcc98b38%2FBlog_Header-V2.png&w=3840&q=75) 9 | 10 | #### AWS and Vercel have always had a shared vision: accelerating innovation through the power of serverless computing—and helping customers win big in the process. 11 | 12 | #### **Today, I am thrilled to announce that [Vercel is now available on the AWS Marketplace.](https://aws.amazon.com/marketplace/pp/prodview-lwqascgzju3bo) This is a major milestone in our relationship with AWS. Additionally, over the last 12-months, we joined the AWS Partner Network and integrated into the Independent Software Vendor Accelerate Program.** 13 | 14 | #### Anyone with an AWS account can now onboard and build on Vercel in just a few clicks. Customers who purchase Vercel through AWS Marketplace have seamless access to Vercel features like: 15 | 16 | - [Serverless Functions](https://vercel.com/docs/concepts/functions/serverless-functions) with AWS Lambda 17 | - [Comments on Preview Deployments](https://vercel.com/blog/introducing-commenting-on-preview-deployments) 18 | - [Frontend Observability](https://vercel.com/docs/concepts/get-started/monitor) 19 | - …[and more](https://vercel.com/product-tour?i=0) 20 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arshad-yaseen/nextjs-appdir-blog/a1bc16577d6d63d11f5a397704385456b6a9e996/public/favicon.ico -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arshad-yaseen/nextjs-appdir-blog/a1bc16577d6d63d11f5a397704385456b6a9e996/public/og-image.png -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./app/**/*.{js,ts,jsx,tsx}", 5 | "./pages/**/*.{js,ts,jsx,tsx}", 6 | "./components/**/*.{js,ts,jsx,tsx}", 7 | 8 | // Or if using `src` directory: 9 | "./src/**/*.{js,ts,jsx,tsx}", 10 | ], 11 | theme: { 12 | extend: {}, 13 | }, 14 | plugins: [], 15 | } 16 | 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ], 22 | "paths": { 23 | "@/*": ["./*"], 24 | "contentlayer/generated": ["./.contentlayer/generated"] 25 | } 26 | }, 27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 28 | "exclude": ["node_modules"] 29 | } 30 | -------------------------------------------------------------------------------- /utils/mdxcomponents.tsx: -------------------------------------------------------------------------------- 1 | import React, { PropsWithChildren } from "react"; 2 | 3 | 4 | const Button = (props: PropsWithChildren) => ( 5 | 6 | ); 7 | 8 | const MDXComponents = { 9 | Button, 10 | }; 11 | 12 | export default MDXComponents; -------------------------------------------------------------------------------- /utils/rehypeoptions.ts: -------------------------------------------------------------------------------- 1 | export const rehypeoptions = { 2 | // Use one of Shiki's packaged themes 3 | theme: "slack-ochin", 4 | // Set to true to keep the background color 5 | keepBackground: false, 6 | onVisitLine(node: any) { 7 | if (node.children.length === 0) { 8 | node.children = [{ type: "text", value: " " }]; 9 | } 10 | }, 11 | onVisitHighlightedLine(node: any) { 12 | node.properties.className.push("highlighted"); 13 | }, 14 | onVisitHighlightedWord(node: any, id: any) { 15 | node.properties.className = ["word"]; 16 | }, 17 | }; 18 | --------------------------------------------------------------------------------