Learn NEXT.JS 14 ð¥ Build a Static Markdown Blog Site
Summary
TLDRãã®ãã¥ãŒããªã¢ã«ã§ã¯ãNext.js 14ã䜿çšããŠéçã«çæãããããã°ãµã€ãã®æ§ç¯æ¹æ³ãåŠã¶ããšãã§ããŸããMarkdownãã¡ã€ã«ã䜿çšããŠãããŒã«ã«ã§ããã°èšäºãæžãããšãã§ããŸãããNext.jsã¯å€æ°ã®WebããŒãžãæ§ç¯ããŠãéåžžã«çŽ æŽãããã¬ã·ãããã°ãäœæããããšãã§ããŸããéçãªãµã€ãã®å©ç¹ãšããŠãããŒã¿ããŒã¹ãžã®ãã©ãã£ãã¯ãæžãããã¢ããªã±ãŒã·ã§ã³ã®ã³ã¹ããåæžããæ€çŽ¢ãšã³ãžã³æé©åïŒSEOïŒã«ãåªããããŒãžã®èªã¿èŸŒã¿é床ãåçã«åäžããŸãããã¥ãŒããªã¢ã«ã§ã¯ãã¬ã·ãããã°ã¢ããªãBubbly Bakerãã®æ§ç¯ã«çŠç¹ãåœãŠãMarkdownãã¡ã€ã«ã§ä¿åãããã¬ã·ãã«ã¢ã¯ã»ã¹ãããµãã«ãŒãã«ç§»åããŠè©³çŽ°ã衚瀺ããæ¹æ³ãåŠã³ãŸãããŸããNext.jsã®ããŒãžãšã¬ã€ã¢ãŠãã®ç¹å¥ãªãã¡ã€ã«ãã³ã³ããŒãã³ãã®äœæãã¡ã¿ããŒã¿ã®è¡šç€ºããããŠéçãªããŒãžã®çææ¹æ³ã«ã€ããŠãåŠã¶ããšãã§ããŸããæåŸã«ããããžã§ã¯ãã«ç¬èªã®ã¹ã¿ã€ã«ãè¿œå ããèªåã ãã®ããã°ãµã€ããæ§ç¯ããããšãæšå¥šãããŠããŸãã
Takeaways
- ð ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãNext.js 14ã䜿çšããŠéçã«çæãããããã°ãŠã§ããµã€ãã®æ§ç¯æ¹æ³ãåŠã³ãŸãã
- ð Markdownãã¡ã€ã«ã䜿çšããŠãããŒã«ã«ã§èšäºãæžããåŸãNext.jsã䜿ã£ãŠãŠã§ãããŒãžãéçã«çæããããšãã§ããŸãã
- ð° éçãªãŠã§ãããŒãžã®çæã¯ãããŒã¿ããŒã¹ãžã®ã¢ã¯ã»ã¹ãå¿ èŠãšãããå¹ççãã€ã³ã¹ãåæžã«åªããæ¹æ³ã§ãã
- ð Next.jsã䜿çšãããšãSEOæé©åãé«éãªããŒãžèªã¿èŸŒã¿ãã¢ããªã±ãŒã·ã§ã³ã³ã¹ãã®åæžã«åœ¹ç«ã¡ãŸãã
- ð GitHubã¬ããžããªãããããžã§ã¯ãã®ã¹ã¿ã€ã«ã·ãŒããšã¬ã·ãã®Markdownãã¡ã€ã«ãååŸã§ããŸãã
- ð» Visual Studio Codeã§ãããžã§ã¯ããéãããšã§ããã¹ãŠã®ããã°ã©ãã³ã°äœæ¥ãå¯èœã§ãã
- ð ïž Next.jsã®`app`ãã£ã¬ã¯ããªã¯ãã«ãŒããšãµãããŒãžãè¡šããã¬ã€ã¢ãŠããšããŒãžã®ç¹å¥ãªãã¡ã€ã«ããããŸãã
- ð `getServerSideProps`ã䜿çšããŠãããŒãžã®ã¡ã¿ããŒã¿ãšã³ã³ãã³ããååŸããéçã«çæãããããŒãžãäœæããŸãã
- ð ããŒãžã®ã¡ã¿ããŒã¿ã¯ãSEOãåäžãããããã«éèŠã§ãããŒãžã¿ã€ãã«ã説æãå«ãã§ããŸãã
- ð MarkdownãJSXã«å€æããReactãšNext.jsãããŒãžã«ã¬ã³ããªã³ã°ã§ããããã«ããŸãã
- ðš ãã¥ãŒããªã¢ã«ã®æåŸã«ããããžã§ã¯ãã«ç¬èªã®ã¹ã¿ã€ã«ãè¿œå ããå人çãªããã°ãµã€ããäœæããããšãæšå¥šãããŠããŸãã
Q & A
Next.jsãšã¯äœã§ããïŒ
-Next.jsã¯ãReactã¢ããªã±ãŒã·ã§ã³ã®éçºã容æã«ããããã®ãã¬ãŒã ã¯ãŒã¯ã§ããéçãµã€ãçæãAPIã«ãŒããåçã«ãŒãã£ã³ã°ãªã©ã®æ©èœãæäŸããŠããŸãã
Next.jsã§éçã«çæãããããã°ãµã€ããšã¯äœã§ããïŒ
-Next.jsã§éçã«çæãããããã°ãµã€ãã¯ããã«ãæã«ãã¹ãŠã®ããŒãžãäºåã«äœæãããããŒã¿ããŒã¹ããããŒã¿ãååŸããå¿ èŠããªããéåžžã«å¹ççãã€é«éã«åäœããããã°ãµã€ãã§ãã
ããŒã¯ããŠã³ãã¡ã€ã«ãšã¯äœã§ããïŒ
-ããŒã¯ããŠã³ãã¡ã€ã«ã¯ãããã¹ãããŒã¹ã®ãã¡ã€ã«ã§ãã·ã³ãã«ãªèšæ³ã䜿ã£ãŠã³ã³ãã³ããæžãããšãã§ããŸããNext.jsã§ã¯ãããŒã¯ããŠã³ãã¡ã€ã«ãéçãªWebããŒãžã«å€æããããšãå¯èœã§ãã
ãã¥ãŒããªã¢ã«ã§äœæãããã¬ã·ãããã°ã¢ããªã®ååã¯äœã§ããïŒ
-ãã¥ãŒããªã¢ã«ã§äœæãããã¬ã·ãããã°ã¢ããªã®åå㯠'Bubbly Baker' ã§ãã
éçã«çæããããµã€ãã®å©ç¹ã¯äœã§ããïŒ
-éçã«çæããããµã€ãã¯ãã³ã¹ãåæžãæ€çŽ¢ãšã³ãžã³æé©åãé«éãªããŒãžããŒãã£ã³ã°ãªã©ããããŸãããŸããããŒã¿ããŒã¹ãžã®ãã©ãã£ãã¯ãæžããããšã§å¹çæ§ãåäžããŸãã
Next.jsã§ã¢ããªãåæåããã³ãã³ãã¯äœã§ããïŒ
-Next.jsã§ã¢ããªãåæåããã³ãã³ã㯠`npx create-next-app@latest` ã§ãã
Next.jsã®ããŒãžãšã¬ã€ã¢ãŠããã¡ã€ã«ã®äºçŽèªã¯äœã§ããïŒ
-Next.jsã®ããŒãžãšã¬ã€ã¢ãŠããã¡ã€ã«ã®äºçŽèªã¯ããããã `page` ãš `layout` ã§ãã
ã°ããŒãã«CSSãã¡ã€ã«ãšã¯äœã§ããïŒ
-ã°ããŒãã«CSSãã¡ã€ã«ã¯ãã¢ããªã±ãŒã·ã§ã³å šäœã§å ±æãããã¹ã¿ã€ã«ãå®çŸ©ããCSSãã¡ã€ã«ã§ãããã®ãã¡ã€ã«ã§å®çŸ©ãããã¹ã¿ã€ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã©ã®éšåããã§ãå©çšå¯èœã§ãã
Next.jsã§åçã«ãŒãã£ã³ã°ãå®çŸããã«ã¯ã©ãããã°ããã§ããïŒ
-Next.jsã§åçã«ãŒãã£ã³ã°ãå®çŸããã«ã¯ãããŒãžãã¡ã€ã«åã®åã«ã¹ã©ãã·ã¥ `/` ãã€ããã ãã§ãèªåçã«åçã«ãŒãã£ã³ã°ãæ©èœããŸãã
Next.jsã§éçãªããŒãžãçæããããã«å¿ èŠãªé¢æ°ã¯äœã§ããïŒ
-Next.jsã§éçãªããŒãžãçæããããã«å¿ èŠãªé¢æ°ã¯ `generateStaticParams` ã§ãããã®é¢æ°ã¯ãéçãªãã©ã¡ãŒã¿ãçæãããã«ãæã«äœ¿çšãããŸãã
Next.jsã®Markdownã³ã³ãã³ããJSXã«å€æããããã«äœ¿çšãããã©ã€ãã©ãªã¯äœã§ããïŒ
-Next.jsã®Markdownã³ã³ãã³ããJSXã«å€æããããã«äœ¿çšãããã©ã€ãã©ãªã¯ `markdown-to-jsx` ã§ãã
Outlines
ð ã¯ããã«ïŒNext.js 14ãšéçããã°ãµã€ãã®äœãæ¹
ãã®ãã¥ãŒããªã¢ã«ã§ã¯Next.js 14ãšãã®æ©èœãåŠã¶ã ãã§ãªããããŒã¯ããŠã³ãã¡ã€ã«ã䜿çšããŠéçã«çæãããããã°ãµã€ããäœæããæ¹æ³ãåŠã³ãŸããNext.jsã䜿çšãããšãããŒã«ã«ã®ããŒã¯ããŠã³ãã¡ã€ã«ã§ããã°èšäºãæžãããšãã§ããŸãããŸããéçãµã€ãã¯ããŒã¿ããŒã¹ãžã®ãã©ãã£ãã¯ãæžãããæ€çŽ¢ãšã³ãžã³æé©åïŒSEOïŒã«ãåªãããããŒãžã®èªã¿èŸŒã¿é床ãåäžããŸãã
ð ãã£ã¬ã¯ããªæ§é ãšãããžã§ã¯ãã®åæå
ãããžã§ã¯ãã®ãã£ã¬ã¯ããªæ§é ã玹ä»ããå¿ èŠãªãã©ã«ããŒïŒrecipes, utils, componentsïŒãäœæããŸãã次ã«ãNext.jsã¢ããªã±ãŒã·ã§ã³ãåæåããå¿ èŠãªèšå®ïŒTypeScript, ESLint, Tailwind CSSãªã©ïŒãè¡ã£ãŠãããžã§ã¯ããæ§ç¯ããŸãã
ð ã¬ã€ã¢ãŠããšããŒãžã®äœæ
ã¢ããªã±ãŒã·ã§ã³ã®ã¬ã€ã¢ãŠããšããŒãžãäœæããããããŒãšããã¿ãŒãå®è£ ããŸããã¬ã€ã¢ãŠãã¯ã¢ããªã±ãŒã·ã§ã³å šäœãã©ããããããŒãžã¯ç¹å®ã®ãã£ã¬ã¯ããªã«è¿œå ããããšã§ã«ãŒãã«å¿ããŠã¬ã³ããªã³ã°ãããŸãã
ð ããŒã¯ããŠã³ãã¡ã€ã«ã®èªã¿èŸŒã¿ãšãã¹ãã«ãŒãã®äœæ
ããŒã¯ããŠã³ãã¡ã€ã«ãèªã¿èŸŒã¿ãgray-matterãšmarkdown-to-jsxã䜿çšããŠã³ã³ãã³ããJSXã«å€æããŸãããŸãããã¹ãã«ãŒãã³ã³ããŒãã³ããäœæããããŒã ããŒãžã«ã¬ã·ãã«ãŒãã衚瀺ããŸãã
ð ããŒãžã®ãªã³ã¯ãšéçãã©ã¡ãŒã¿ã®çæ
åã¬ã·ãã«ãŒãã®ãªã³ã¯å ãèšå®ããNext.jsã®åçã«ãŒãã£ã³ã°ã䜿çšããŠãã¬ã·ãã®è©³çŽ°ããŒãžã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãããŸããéçãã©ã¡ãŒã¿ãçæãããã¹ãŠã®ã¬ã·ãã«å¯ŸããŠéçãªããŒãžãäœæããŸãã
ð ããŒãžã®éççæãšã¡ã¿ããŒã¿ã®èšå®
ããŒãžãéçã«çæããå¿ èŠãªã¡ã¿ããŒã¿ãååŸããŠããŒãžã®SEOãæé©åããŸããåã¬ã·ãã®ããŒã¯ããŠã³ã³ã³ãã³ããååŸããèšäºããŒãžã«ã¬ã³ããªã³ã°ããŸãã
ðš ãããžã§ã¯ãã®ã«ã¹ã¿ãã€ãºãšæåŸã®touches
ãããžã§ã¯ããã«ã¹ã¿ãã€ãºããã°ããŒãã«CSSãå€æŽããããšã§ãå人çãªã¹ã¿ã€ã«ãé©çšããŸããã¬ã€ã¢ãŠãå ã®ããŒãžã¡ã¿ããŒã¿ãæŽæ°ããŠãã¢ããªå šäœã®ã¿ã€ãã«ãäžè²«æ§ãä¿ã¡ãŸããæåŸã«ããã¥ãŒããªã¢ã«ãéããŠåŠãã ããšã掻ãããèªåã®ããã°ãµã€ããäœæããããã«ã¹ãã«ãåäžãããããšãã§ããŸãã
Mindmap
Keywords
ð¡Next.js
ð¡éçã«çæãããããã°ãµã€ã
ð¡
ð¡Markdown
ð¡SEOïŒæ€çŽ¢ãšã³ãžã³æé©åïŒ
ð¡Routing
ð¡Components
ð¡Styling
ð¡Server-side Rendering (SSR)
ð¡Metadata
ð¡Efficiency
Highlights
Next.js 14 tutorial introduces building a statically generated blog website using markdown files.
Demonstrates creating a recipe blog called 'Bubbly Baker' with markdown files for recipes.
Explains the efficiency of static site generation for reducing database load and improving SEO.
Guides on initializing a Next.js project with configuration options like TypeScript, ESLint, and Tailwind CSS.
Overview of the project structure including the app folder, pages, and styling with CSS.
Introduction to creating dynamic routes for recipes using square brackets for the slug.
Explanation on using 'gray-matter' and 'markdown-to-jsx' for parsing markdown and converting it to JSX.
Walkthrough on setting up a layout component to wrap and style the entire application consistently.
Creating a 'postcard' component to display recipe cards on the homepage.
Utilizing 'get-post-metadata' function to fetch and display metadata for recipe cards.
Description of generating static parameters for dynamic routes using 'generateStaticParams' function.
Ensuring SEO-friendly by generating metadata for each static page with 'generateMetadata' function.
Fetching markdown content and rendering it on the page using 'markdown-to-jsx'.
Static site generation process explained for building pages at build time for efficiency.
Incorporating interactive routing to navigate between the homepage and recipe pages.
Challenge to customize the project for personal skill development and practical experience.
Encouragement to explore additional styling and components for a more personalized blog site.
Summary of the tutorial's coverage on static site generation, Next.js components, and SEO optimization.
Transcripts
welcome my friends to this nextjs
tutorial where not only will we be
learning nextjs 14 and everything that
comes with it all the cool features and
functionalities but we'll also be
learning how to build a statically
generated blog website now this is an
incredibly useful thing to know how to
do and nextjs allows us to do it with
markdown files so we can write out a
blog post in a local markdown file and
in this tutorial we'll learn how we can
get next J to statically build out a
whole lot of web pages to create a
really awesome recipe blog you might
also be wondering why I have my small
James website open and that's because
this is actually a statically generated
blog site made with nextjs if we come
into the notes directory here I have a
whole lot of notes these are just
markdown files that I have got next
chest to turn into static web pages I
can click on one and then it all looks
absolutely beautiful so it's basically
just a blog site we're going to learn
how to do it and if you're not familiar
with what a statically generated blog
site is basically if you think about a
Blog it's got thousands of blog articles
each one of those is at a sub path so
you might have blog SL learn how to code
or something like this here we can see
this one's notes htmlcss and where
originally someone might come to that
web page and you could fetch all the
data from the database and load it in if
you have a whole lot of users visiting
that website the traffic to your
database is going to be insane so it's
really inefficient instead we can use
nextjs to statically build the page so
what this means is that it takes the
blog article it takes whatever data it
has in this case it's going to be our
markdown files and when we build our
nextjs site nextjs is going to build all
of the sub Pages we need for our website
so basically they're all pre-prepared we
don't have to fetch any more data and so
when a user visits that Blog Page the
page is already loaded we don't have to
fetch any data and it's infinitely more
efficient so this is really good if you
want to cut costs on your application
it's also absolutely brilliant for
search engine optimization not to
mention that your pages will also load
much much faster now in this tutorial
we're going to be building a recipe blog
app here it's called the bubbly Baker we
have a whole lot of recipes these are
all saved in markdown files which we'll
learn how to access later and if we
click on a recipe we get taken to the
recipe sub route so the recipe blog sub
route and here we can access the whole
recipe we can see that the page meta
information is updated we can route back
to the homepage super fast really quick
and very easy to make with nextjs so
overall it's going to be an absolute
winner of a tutorial if you enjoy the
video smash the like And subscribe
buttons love that support and with that
all said let's get into the code so it's
now time to get our hands dirty with
some programming and the first thing
we're going to do is open up a terminal
or a command line and I'm in my project
directory where I have all of my
projects and this is where we're going
to initial iiz our nextjs project now
just before we do that there's a few
things you should know first off if
you're not that familiar with react the
react JavaScript framework there's a
link to a tutorial in the description
down below that will bring you up to
speed it does help for building nextjs
applications furthermore if you have any
questions you're welcome to ask them in
the Discord Channel and finally the link
to the GitHub repo is also available in
the description down below and we'll
need that because the application we're
building today is pre-styled so we're
going to focus on learning nextjs and we
don't have to worry about styling our
whole application so the CSS file for
the project will be available in the
GitHub but we will get to that together
very shortly now to actually initialize
a nextjs project the first thing we're
going to do is head over to the nextjs
documentation also linked in the
description down below and here we are
going to use the command npx create next
app at latest so if we come back into
our terminal we can type that in npx
create-- app at latest and then we can
name our app so I'll call this project
static recipe blog if we hit enter
that's going to prompt us for some
configuration for our project do we want
typescript absolutely not es lint yes
tailin CSS this is not going to be a
tailin CSS project Source directory no
we do not want that the app router yes
we do and The Last One Import Alias and
that's going to be a
no so that will go ahead and install our
nextjs project for us and now that that
is all done I can go ahead and open up a
vs code window Visual Studio code window
this is where we'll be doing all of our
programming if you don't have this
installed a link to install vs code will
be in the description down below and in
here we're going to head open we're
going to come over to our projects
directory click on the static recipe
blog and hit open that's going to bring
our project up for us here we can see
all of the files and and the folders
that we will be needing for our next
year's project so just to quickly run
through our directory here we have an
app folder this is where all the magic
in our project is going to happen we've
got some special Pages notably the
page.js and the layout. JS we also have
a modular CSS sheet a page. module. CSS
we're going to go ahead and delete that
file cuz we do not need it additionally
we have a node modules file we won't be
touching that we have a public directory
where we can save any local assets and
then we just have some configuration
files such as our package.json and a
readme which also happens to be written
in markdown so isn't that handy dandy
now the first things we're going to do
in our project is create a folder called
recipes we're also going to create a
folder called
utils and we're going to create one more
folder called
components now all of these folders are
created in the top level directory so
not inside of the app we can see they're
all setting adjacent here and they're
just going to be for organizing all of
our code if we open up our app we can
come in here and we have a pre-styled
home route we're going to go ahead and
delete everything in the in the page.js
route so all we're left with is a basic
react functional component here we have
a function it's called home and it
returns something where this something
is known as jsx
so in here we'll have our main tags and
that's going to be this file for the
minute now the next thing we're going to
do is we're going to download all of the
markdown files I'm not going to get you
to write out all of the recipes I
prepared them for you in addition to all
of the styles for our project if we come
into the global. CSS we can delete
everything and what I'll want you to do
is go over to the GitHub repo that's
Linked In the description down below if
you click on that and find the the app
directory you'll find the global. CSS
file and that will have all of the
styles that you can just copy or you can
download the file directly and save it
inside of the app directory so here I'm
going to copy everything across and now
my project is completely styled and we
don't have to stress about
it also if you're in the GitHub repo if
you could start it that would be amazing
super appreciated and while you're there
the other thing you'll want to get is
the six markdown files you'll find
within the recipes folder I'm just once
again going to go ahead and copy them
across we have six in here we have a
markdown formated recipe with some
metadata up the top and as I mentioned
you can just copy them straight across
from the GitHub as well now these recipe
files are the blog posts so you could
make a whole lot of extra blog posts you
can continually add them to this recipes
file you could create different
subcategories of blog posts and
essentially you just make one you add
the metadata and you write out your blog
article using the markdown syntax now if
you're not familiar with the markdown
syntax I also have a video on that
Linked In the description down below
that you could go and check out it's
about 8 minutes or something really
short it's a very nice syntax to learn I
use it for all sorts of note taking and
I'd recommend packing it up it doesn't
take long so now that we've done all of
our admin for our application the next
thing we're going to do is go ahead and
open up a terminal within our Visual
Studio code window now one way you can
do this is by hitting control shift p
and the menu will come up the top and
you can hit toggle terminal and that
will pop it up you should also be able
to open up a terminal from the file or
folder options available once we have
this terminal up and running we can come
in here and type npm run Dev hit enter
and that's going to boot up our app on
probably Local Host 3000 VI it's going
to be 3,2 for me and we can come back
over to a browser and we can paste that
URL in and if I move this window to the
side we can see that we have a totally
blank application perfect just the way
we want it now currently this blank
application is loading in our Global CSS
Styles into the layout we can see here
we have imported the global. CSS file up
the top and the first thing to note is
that this app directory represents the
routes and sub pages of our
application so at the top level of our
app Direct
we have two special files we have a
layout and we have a page now the page
and layout keywords or file names are
reserved in nextjs they have special
meaning with the layout is a wrapper of
our page so that's where we're going to
wrap our entire page at this particular
path so the Home Path and if we open
this up we can see in here we have the
body and inside here we have some
children contents now the children is
everything contained within our layout
specifically the page so the page gets
rendered within the layout now once
again these are both just functional
components here we have a function
called root layout it receives the
children contents which is just whatever
it contains whatever it wraps and that's
just everything in the page now we're
also going to create a new folder inside
of the app directory and this is going
to be called recipes and in here we're
going to create another subfolder and
this is going to have square parentheses
because it's going to be a dynamic path
name and we're just going to call it
slug because it's a dynamic path Slug
and in here we're going to right click
and we're going to create a new page.js
file and this page.js file is what will
be rendered when we get to the app SL
recipes SLS slug whatever that Dynamic
slug is route and we'll see how that
works in a second in here we're just
going to create a default default
functional component and I'm going to
call this recipe page and we're just
going to return a div that says hello
world now just to really clarify the way
that this works here we have the app
directory and if I come into the page.js
and type some
ASDS refresh the page we see that's what
shows up on our home page now instead if
I come over and I type SL
recipesbanana muffin
we can see that hello world gets
rendered on the page so that is matching
the pathing that we're doing inside of
the app directory and the page is what's
being rendered within that directory
within the layout now the layout wraps
our entire application it's just the
pages that we add at these specific
directories you can technically have
nested layouts but I wouldn't worry
about that at the minute now one quick
thing I'm going to do is just rename
this file here instead of recipes I'm
just going to call it re recipe cuz it
will be a singular recipe that we render
and we can see that now broke our little
page right here until I once again match
the paths
up so that's pretty cool we've set up
the pages for our application the next
thing we're going to do is install some
dependencies for our
project namely we're going to have npm
install inside of our terminal the first
one's going to be gray- matter and then
we're going to have a space and we're
going to install another one called
markdown D2
djsx and essentially gray matter is
going to be used to read the contents of
our markdown file and then the markdown
jsx is going to take the markdown
content that's been read onto our page
and convert it into jsx which is
essentially what react and nextjs render
onto the page so that's pretty
straightforward and with that installed
we can go ahead and boot up our
application Again by typing npm runev
now the first component we're going to
be working on is the the layout. JS it
wraps our application as I said before
where the children content that gets
wrapped Within These curly parentheses
is basically JavaScript that we can
render inside of this HTML section and
that's just going to display everything
that gets wrapped by this component
inside of here inside of the function
I'm going to create a variable called
header and that's going to have some
circular parentheses and inside here I'm
going to have the header tags opening
and closing tags and then I'm going to
do the exact same for footer so let
footer equal to and then I'm going to
have some footer tags as well now if we
enter this onto a new
line have the children in the middle
currently the children is going to be
these main tags because our layout wraps
the page the page Returns the main so
the main is what becomes the children
above the children Contents I can now
use the circular parentheses to render
out my header which is just what we
created above and beneath I'm going to
render out my footer now if I come in
here and type all sorts of random stuff
like so and if we come back to the home
R we can see that that information does
in fact show up it's a shame I use the
similar keywords for all of them because
it obviously looks very similar but we
now have our header at the top of the
page the main content in the middle and
the footer down the bottom we can do the
footer first that's pretty
straightforward it's just going to be a
paragraph tag that says made with and
then we're going to use a little heart
emoji just cuzz that's
cute I might actually go for a yellow
heart it's a bit less
intimate uh where is it right there so
it's pretty fun that shows up down the
bottom nice and easy perfect made with
love the next one we're going to do is
the header now the header is going to be
an H1 tag except we're going to wrap it
inside a link tag where the link is a
nextjs specific tag so it has a capital
letter if we hit enter on the
intellisense that's going to import the
link component up the top of our
page now if we create the opening and
closing tags we're going to want to wrap
our H1 that's going to say the bubbly
bacer that's the name of our recipe
app and we can see our application's not
happy and that's because a link which
works in the same way as an anchor tag
does needs an hre and this is just going
to be a slash now the reason we're doing
this is because our header wraps our
entire component our entire web page and
since it's inside of this layout it also
wraps any subdirectory pages so when I
consequently come over to SL recipe SL
whatever the name of the recipe is we
can see the header and the footer are
still here so they wrap our entire
application even if the contents within
the pages changes and the benefit of
doing it like this is now now we created
a link where the link just has an hre
that's a forward slash that's the Home
Route this is available on any page and
so now if I click it currently we're on
the recipe ASD route if I hit that it
takes us back to the homepage so that's
just really easy super simple a nice way
of adding intuitive navigation to our
web
page so now that we have our header and
our footer done the next thing we're
going to do is start getting busy with
the actual recipe cards on the homepage
and for this there's a few things we're
going to do the first thing is creating
a component and this is going to be
called recipe well actually I'm going to
call it postcard. JS and here we're
going to export a default function
called postcard where the post and card
are going to be capitalized and in here
we're going to return some jsx this is
going to be another nextjs link so we're
going to have to import that up the top
of our
component and in here we can just for
the minute provide it an empty hre so
it's just an empty string so that it is
happy now we'll fill that out more in a
second but the next thing we have to do
is actually get all the posts read them
from our local files inside of this
recipes folder and we're going to do
that by creating a function inside of
utils called get poost
metadata. JavaScript .js now inside of
this it's not a functional component we
didn't give it a capitalized name so
it's so it's just a regular Javascript
file we need to import a few things
namely the file system module so we're
going to say import FS from fs and we'll
also need to import mattera from Gray
matter which is how we're going to read
all of our local
files after that we're going to define a
function called get post
metadata and that's going to take a base
path and in here what we're going to do
once we've opened up that function is
we're going to say const and we're going
to define the folder where we look for
these posts and that's going to be equal
to the base path that we pass in plus a
forward slash after that we're going to
access all of the files so we're going
to say cons files and that's going to be
equal to file system. readdir sync
synchronously and we're going to pass
the folder and then after that we're
going to read only the markdown files so
we're going to say const markdown post
is equal to files. filter and we're
going to use the array filter method and
this is going to take a file and we're
going to use an arrow function and we're
only going to include a file that ends
with theark down extension file
extension so now that we have access to
all of the posts we can get the file
data using the gray matter Library so
I'm going to say const posts is equal to
all of the markdown post and I'm going
to use the map method where the map
method takes an arrow function as an
argument and in here we're going to get
the file name so that's the name of the
file and now we're going to say const
file contents is equal to fil system.
read file synchronously then we're
inside of this we're going to call it an
AR we're going to call it as an argument
and pass in a template literal string
and that's going to be the base path SL
the file name now the base path and the
file name are both wrapped in the dollar
sign Cy parenthesis cuz that's how we
pass in some JavaScript to our template
literal and then we're going to pass in
the file encoding which is just going to
be
utf8 just like that very easy once we
have all the file contents now we can
say const matter result is equal to and
we can call matter now we imported
matter from the gray matter library and
we can just pass in the file contents
and once we have that we can return an
object this is what gets passed into our
actual
component and we just want to access all
of the meta information about our
recipes so if we come in here we can see
the meta information is available
between these triple dashes so we have a
title a prep time a cook time and a
description so we're going to get access
to all of them we're going to say title
is the key and the value associated with
that is matter result. dat. tile make
sure we spell that
correctly after that we're going to have
the prep time and that's going to be
matter result. dat. prep time then we'll
have the cook time that's going to be
matter res. dat. cook time the next one
is bio and that's going to be matter.
data.
description and then finally we're going
to have the slug we're going to return
the slug which is just going to be the
file name. replace and we're going to
replace the MD with an empty string just
so it looks a bit pretty now up the top
here we're going to export uh this
function as the main export from this
file so we're just going to add the
export default in front of the function
definition like so and the one last
thing I forgot to do is after posts we
just have to come down and return posts
from the function so now that we've done
that we can come back into our page
right here this page.js where we have
our home functional component and we can
get access to all of our posts so we can
say cons post metadata is equal to get
post metadata we can see that import
showing up right here so if I hit enter
on that intellisense it's going to
create the necessary import for us and
now I can call that as a function and
pass in the directory where I should be
looking for these markdown posts so if I
save that and now if I come in here and
say console.log post
metadata we can see that on the server
side we've accessed all of the post
metadata that we can Now display on our
screen so that's super
convenient it's a nice list so what I
can do in here is I can create a div
that has a class name of post
container where post container is a
style that's already created inside of
the global CSS and in here I can use the
circular parentheses and I can map out
some post cards so that's going to be
cool or recipe cards so I can say post
metadata. map
and I can call this one the post I can
get the post index as the second
argument and that is our Arrow function
and from the arrow function I can return
and in here I can just return the post
card or the blog card or the recipe card
whatever you should call it and whenever
we use a map whatever we return the top
level needs to have a unique key which
is why we got the post index in as an
argument in our Arrow function now I'm
also going to add the recipe or the post
as a prop to the postcard component so
that we can access it within the
postcard and I'm now going to remove
that console log So currently not much
shows up but that's because our postcard
is pretty empty we've passed in some
props so we need to receive some props
and in here what I'm going to do is
create this component so first up we're
going to say const post is equal to
props so we're going going to
destructure post out of props which is
going to be the object that contains our
metadata for that particular recipe card
inside of the link we're going to create
a div this is going to have an H3 in
it now the link itself is going to have
a class name of unstyled so we can get
rid of any weird link styling the parent
or container div is going to be called
post
card uh where the C has a capital
c inside of here we're going to have the
H3 then we can have the curly
parentheses to render out some
JavaScript this is going to contain the
post title underneath that we're going
to have a paragraph tag that's going to
have the post bio beneath that we're
going to have a div with the class name
of stats
container and in here we're going to
have another div and this is going to
have an H5 that says uh uh prep
time like so beneath that we have a
paragraph that's post.
prepore time and then what I'm going to
do is copy and paste this element just
underneath and change this to say cook
time likewise just here I'll replace
that to say
cook so if we go ahead and save that
just like that we have created this card
that shows up and if I click on it
currently nothing is going to happen
because it's just routing us to the
homepage but in a second we're going to
provide an hre and that's going to
actually rout us to the necessary page
now this is pretty cool it's nice and
responsive looks sufficient and once
this project is complete I challenge you
to go out and restyle it if you really
want to practice your skills and become
a bit an xjs developer adding your own
flare and adapting the code in a
tutorial is a great way to learn and
gain confidence programming by yourself
if you do that I'd love to see what you
guys guys come up with so you can always
share that with me in the Discord
Channel now the other thing we have to
do is come back and handle this href
right here that's pretty straightforward
that's just going to Route us to we're
going to use a template literal string
and that's going to be SL recipe SL
dollar sign curly parentheses and that's
going to be post.
slug so now if I click on this card that
takes us to this subsequent route then
if I click on the bubbly Baker I get
routed back so that's pretty nifty now
we haven't really Incorporated any
special nextjs features just yet but we
have got the routing all working and so
with that all done we can come over to
our page.js now inside of here a fair
bit of magic is going to happen so that
everything is statically
generated the first thing we're going to
have to do is import a bunch of stuff so
we're going to import markdown from
markdown to jsx we're going to import
get post post metadata from our utils
we're going to import react from react
we'll also need to import the file
system from file system and finally
we'll import matter from Gray
matter now the next thing on our list to
do is create a function called get post
content and this is just going to be a
utility function that takes a slug and
it fetches the content from the markdown
post that matches the slug so that's why
we passing a slug and now what we can do
is we can say const folder set that
equal to recipes then a forward slash
now we can Target the file the file is
going to be at the route of the folder
plus the back text we can have the
slug right here and a template literal
string and we can add on the markdown
extension and now what we can do is
access the content so that's going to be
equal to file system. readfile
synchronously we can access the file and
pass in the encoding which is
utf8 and now that we have the contents
we can say const the mattera
result pass the file say that's equal to
mattera and just pass in the
content finally we can return the
mattera result which is just all of our
markdown content almost as raw text so
that's pretty cool that's going to get
the content from the post now the next
two function we're going to Define are
going to make this page statically
generated we're going to get all of the
information we need at build time so
that we can build these static pages and
we'll have a second function that's
going to ensure we have all the
necessary meta information for the page
as well so that we have good search
engine optimization and all that good
stuff so the first function we're going
to Define is going to be called export
const
generate static params and that's going
to be equal to an asynchronous function
note that I'm using the arrow syntax
here and in here we're going to say
const post is equal to get
post metadata we're going to pass in the
recipes directory as an
argument we imported that function from
above and now what we're going to do is
we're going to return post. map post
this takes an arrow function that
receives the post and then we're going
to return the circular parentheses with
an object so the object is what's
getting returned and that's going to
have a slug that's called post. Slug and
essentially what's going to happen is
when we build the pages it's going to
get all of the posts and then it's going
to create a URL or a page for every post
slug that it finds so essentially we'll
end up with static pages for all of
these directories right here and these
are going to be the relevant slugs so
that's pretty cool we can have it
generate a whole lot of static Pages for
us the next thing we're going to do is
Define an asynchronous function and this
is going to be called generate metad
data now this is back to our good old
syntax from before and this is going to
allow us to get the metadata for the
page and here we're going to receive the
pams and the search pams now notice I've
wrapped them inside of the curly
parentheses which means that they're
getting destructured from whatever
argument is passed into the function
inside of this regular function we're
going to get the ID so the ID is going
to be equal to the page parameters then
we're going to use the optional chaining
syntax to check for a slug if the slug
does exist then we're going to return
something otherwise we're going to
return something else so in the case
where the slug does exist just like up
here we're going to return the
multiplication dot I like using that and
then we're going to add on on to that
the params and the slug the Turner
Operator just here is a conditional
check so this check basically says all
right we want to define the ID we're
going to check if the slug exists if it
does we're going to assign this section
right here to the ID otherwise we're
just going to assign an empty string
after that we're going to return and the
title of the page is going to be a
template literal string and this is
going to be the bubbly
Baker remember the title is the metadata
title so that's what comes up up here
and then we're going to have a space and
in here we're just going to use the
template literal syntax and we're going
to throw in the ID and we're also going
to replace every instance of an
underscore with a space so that we don't
get any weird underscores from these
file names right here so that's going to
generate all of the metadata for the
static pages that we want to build all
of the static Pages we basically have a
static page or we return a static page
for every markdown recipe and our
recipes folder now we can actually
Define the contents that's going to go
inside of the statically generated Pages
the pages that get built in build time
and are saved cached so that they're
built once they can be used a whole lot
and we only have to get the data once so
the first thing we're going to do is
receive some props inside of our recipe
page and from the props we can get the
slug which is the name of this
particular page so the slug is equal to
the props do the parameters of the page
do slug so once we have the slug that's
basically this fell right here slug
whatever it is that end URL that end
path that we're at once we have that we
can say con post and that's equal to get
post content which is this function we
defined up the top right here that takes
the slug and that's going to get the
content that's literally inside of that
post so we can just pass in the
slug and now we should be able to
console.log the post and see all that
information pop up so if I inspect our
page and come in here and we click on
that link nothing's happening and that's
because it's a server side page so down
here we can see we have all of the uh
contents so the console is on the server
side in inside of our terminal so that's
pretty cool we have all of this uh
content right here that we can now go
ahead and access and so what we're going
to do is we're going to come in here
we're going to swap these dibs out for
Mains because this is the file that gets
wrapped by by our header and footer we
essentially have to match the main
syntax so it's the main body of our
document on this page this is also going
to be the main body of our document
inside here we're going to have an
article tag because it's semantically an
article and inside of here we're going
going to render out the markdown which
we imported above from the markdown to
jsx and inside of the markdown tags
we're going to render out the post.
content if you remember when we looked
in here the post. content is all this
wacky stuff right
here there's all of the content so we're
just going to render that out on the
page so if we go ahead and save that now
we can see our markdown post gets
rendered on the page we can also Al see
that the metadata for our page is
updated so here we have the bubbly
baker. applepie that's the subdirectory
this is the apple pie if we go back home
we get create next app so we'll fix that
in a sec and we'll learn how to add
metadata to a home
route but then if I click on the banana
bread the bubbly Baker banana bread
route updates so our title our page meta
data is all sorted these pages are
statically generated so they're built at
built time they're saved and then the
data is red we don't have to refetch the
data every time a new user loads the
page so it's incredibly efficient super
fast and good for the bank depending on
your hosting configuration if we click
on the bubbly Baker it routes us back
home so that's pretty cool everything is
nice and responsive and suddenly you can
see how you could make a massive blog
site just from this very simple syntax
throw in some extra styling add a few
more blog posts and you know Bob's your
uncle now the one last thing we're going
to do before we're done is come back to
our layout up here and we're just going
to change this page metadata to the
bubbly Baker as well so everything
matches and the description for this
page is going to be my amazing recipe
app pretty straightforward and so now
the title is updated to match we have
the bubbly Baker I can click on one we
go to the banana bread I can come back
home and we have all of our recipes and
just like that we've learned how to make
a static blog site with the nextjs we've
learned how to statically generate the
pages everything is server side rendered
so it's incredibly good for search
engine optimization it's super fast as
well we've also learned about how to
make nextjs components we learned about
the reserved page and layout files we
learned how to create components map out
different components fetch all the posts
render out the Met information pass
through all the markdown and show it on
the screen as I mentioned at the start
of the video my website is literally the
exact same foundational skeleton so you
can make all sorts of wicked stuff just
from this code we have put together in
this tutorial as always I highly
recommend you go and make some
personalizations to this project change
some of the Articles make your own blog
site make it look different fiddle with
the Styles you could even get rid of the
global CSS and add tailwind and style
out your application that way that's
what my website is that's Tailwind
instead as always if you've enjoyed the
video smash the like And subscribe
buttons thank you guys so much for
watching I hope you've learned a lot and
I'll catch you in the next video peace
learning to code if so be sure to check
out the learn to code road map or dive
straight in with these
videos that's a good
one
Browse More Related Video
5.0 / 5 (0 votes)