(English) Nuxt 3 - Course For Beginners (DownSub - Com)
(English) Nuxt 3 - Course For Beginners (DownSub - Com)
web. It makes it
very easy to create server rendered applications, static websites and single page
applications.
And it's a popular choice for developers looking to build fast and scalable web
applications.
instructor on Udemy. Let's start learning. Hello, everybody, and welcome to this
course about
Nuxt 3. My name is Guillaume and today I'm really excited to introduce you to my
favorite framework.
Nuxt is a framework made on Vue.js and you might know that last year Vue.js
upgraded to the version
3. So Nuxt did the same and now we have all the features of Nuxt 3. With Nuxt.js
you can create
full stack application and it's a very interesting framework because there are
several rendering
modes. During this course we are going to learn everything you need to know to
create a full stack
application with Nuxed. Here is the program of our course. We are going to learn
first how to create
an application. Then we are going to look at pages and routing the file system that
help us to create
routes automatically. We will look at components and the main feature of Nux is to
auto import the
components. How to create layouts. How to deal with images and assets. We are going
to look also
at composable, the new feature of Vue 3. How to create plugins and why. How to deal
with middlewares
to prevent authentication, for instance. We are going to learn what are modules, a
specification
of Nux.js that help us to supercharge our application. We are going to talk also
about
state management and especially about Pinar. One of the most interesting part of
this course
is talking about the rendering mode with SSR, SWR and eBread mode, the new mode.
Finally we are going to look at servers with Nitro, how to create a server on our
app.
We will need also to know what are use fetch, use lazy fetch, use async data, those
methods provided
by Nux 3 to fetch data. Also if you are interested to work with Nux, you might be
interested also in
SEO and methods for the rendering modes. We will look at lifecycle hooks, how to
configure our
project. Then finally we will finish our course on Nux content, a package or module
that help us
to create static website with Nux. And finally we will create a full stack
application which will
be a documentation and an API. So if you are ready to follow this course, let's go!
top of Vue.js, a bit like Nuxt.js for React. And there's a lot of features that
help us to develop
faster and that improve our developer experience. So when you go on nux.com, the
official
documentation, we see now that we are on the version 3 of Nux. Because yes, Vue
switched
recently to the version 3. So Nux had to update its latest version. So when we
click on get
and we are going to go down and here we see that we have a command npx nuxi init
project name. So
I'm going to copy paste that, go into my terminal, I'm going to give a name so it's
going to be my
Nuxt project. And there we go, my project has been installed. The first thing we
can notice when we
arrive in this Nuxt project, and if you already did some Vue.js before, is that
it's really light.
There's only six files at first. So when we are going to type npm install, we're
going to have our
node modules. However, we don't have the folders that we have on Vue 3. For
instance, on Vue 3,
we get the source folder, we can have the public and assets. With Nux, it works a
bit the same.
However, the difference is that we will not have any source folder at first. We
will have to create
our own folders, page components, et cetera, et cetera. And it's going to work like
this because
Nux is providing to us a file routing system that works on the organization of our
folders.
It will automatically create our routes. And another thing that is really cool is
that with Nuxt.js,
it's going to auto import our components. So we will not have to import all of
this.
But we are going to see that in the next lesson. Type npm install to npm install
our project.
Then we are going to type npm run dev to just launch it in our browser and to look
at it at first.
Okay, this is done. And the first thing we can notice is that we have a node module
folder.
And we also have this point Nux folder. Yarn dev or npm run dev, it depends. And
here I'm
going to open my localhost 3000. And there we go. We've got our application
running,
which is actually this Nux welcome only. So our application is now set up. We can
use it
directly like this. If you want it, you can deploy it from now. It will work as
it's supposed to work.
And what we're going to do at first is just to remove this and put hello Nuxt 3
because we don't
need that component. All right. Our app has been created, but it's totally empty.
The first thing
I'm going to do is to add a bit of configuration. Because, yes, with Nuxt, yes, we
have a Nuxt.config.
called define Nux config that receive an object. And in this object, we can pass
several elements.
The topic of this course is not to talk about the configuration. The topic of this
course is just to
in order to follow every step. So the first thing I'm going to add, it's an alias.
This alias will
help me actually to catch some elements directly from the source. But you are going
to say to me,
Guillerme, you talked before about the auto import feature. Auto import is working
for pages and
components and some other folders, but not necessarily for everything. So we will
necessarily
need an alias. So this alias will be an at. Okay. And here I'm going to say, hey, I
need the paths
of my current project. And I want to be at the root. So I'm going to import resolve
from pass
up there. All right. And here I'm going to resolve a pass. So I'm going to start
with dear name.
And here it's going to be just the source, the root, actually, of my source. Okay.
So now when
I'm going to type at everywhere in my app, it will resolve directly the dear name.
So the dear name,
which is actually the root of my folder. And I will be able to catch anything and
to import
dynamically every element of my project. Another thing is that I want to add a CSS
file because
we don't have any style in there. So what I'm going to do, I'm going to create a
folder directly,
which will be assets. And in this assets, I will add a main.css. If you want to add
a CSS,
it's okay. Me personally, I'm going to add a CSS. What I need to do now, it's to
install
SAS because SAS is not installed. So I'm going to type npm install SAS, and I'm
going to launch
again the project. And what I want to do, I want that this main.css file would be
actually
root style sheet of my project. So what I can do is to type CSS. And CSS, actually,
it's an array.
So I'm going to specify on this next.config.ts that I want to have one file as a
CSS root file.
You can have many other because it's an array. So here I'm going to add assets
main.scss. To
check if it's working, I'm going to add a body and here it's going to be color red.
And when I get
back, there we go, we see that I have the color red apply. So it is working, it is
applying my
SCSS. Finally, for the need of discourse, I'm going to install Tailwind CSS. So I
go on Tailwind CSS
on Get Started. Then I click on Framework Guides. There I click on Next.js. And I
go on the version
three because here we are on the version two. So here we arrive there and we see
that we have to
install Tailwind CSS in our terminal. So I'm going to copy paste this going back
there. I'm going to
stop npm install Tailwind CSS. There we go. Then I need to init my file. So I'm
going to type npx
tailwind css init. Then we need to specify to nux.config.js to use post css and
tailwind.
So I'm going to copy paste this and I get back there. And just after my
configuration,
I'm going to add post css plugins, et cetera, et cetera. All right. Then finally,
what I need to do
also, it's to add actually to the tailwind.config.js right now, which is almost
empty. It's to add
here the content file that I need to watch. So let's have a look on this. I'm just
going to copy
paste and we're going to look at it. We will watch for components. So there will be
a components
folder. We will watch for layouts because they can be a layout folder also. Pages,
which will be the
pages of our project. Plugins, but also for the nux.config.js and of course the
app.view.
So now it's done. What we need to do is to add those elements, tailwind base,
component and
there on the CSS line there. So when I get down, it's telling us to do it, but we
already did it.
And now let's run again our project and let's see if it's going to work. And when I
get back to
localhost 3000, there we go. I think it's working because the font has changed. And
if I go to the
network on main.scss, we see that tailwind is clearly imported. If you want to get
this starter
project, you can go on my GitHub and down there you got the nux3 tailwind starter.
And when you
click on it, you have the full repository available that you can clone directly.
Finally, we are ready
to follow this course and to learn how to create a front-end application with nux3.
One of the main features of nux3 is its file system routing. What does it mean?
Basically,
in view3, you are supposed to install viewrouter to deal with routing. Then you
will have to create
a root.js file, declare your routes, import your component or pages, and then
organize all the
nested routes, the navigation guard, et cetera, et cetera. With nux3, you don't
need to do that
because there's a system inside nux3 that helps you to deal with the routing
automatically.
And it's working with the pages directory. So we see here on the official
documentation that
every view file inside the pages directory creates a corresponding URL. So let's
get back to our app
and let's try to create a route. So I'm going to create a new folder called pages.
And inside these
pages, I'm going to create, for instance, an events.view page. So here it's
supposed to be
slash events as a corresponding URL. So I'm going to create a quick template. And
in this
template, I'm going to type div events page. All right. It's good. But remember, in
my app.view,
I have this. And normally, with viewrouter, if you're already coded with view,
you're supposed
to use the router view built-in component that is provided by viewrouter. How does
it work with
nux3? Well, if we go back to our app, we already got an error. And if we try to
access the page
events, we have actually the page of app.view. And this is a bit confusing because
we're supposed
to have events page and we finally have a app.view. It's really easy to understand.
We have to say to
nux3 to use the router. So first, we are going to use a first built-in component,
which is nux3
layout. Because later, we are going to use the layout of nux3. And inside this nux3
layout,
we are going to use the router view built-in component. But actually, it's not
router view.
It's nux3 page. nux3 page here is working exactly like router view component with
viewrouter.
Now I've did that. I can get back. And on my slash events root, I got the events
page
here display. However, if I get back to the root of my app, I got a 404. And it's
totally simple
to understand. I don't get any index at the root of pages. However, app.view is
supposed to be the
root of our single page application. And it needs the first page to start. And this
first page has
to be index.view inside my pages folder. So I'm going to type template div. And I'm
going to say
here index page simply. So I got an index.view, which is the first page. So the
root URL of my
application. Then I got slash events that is displayed there. So when I get back
and I update,
so maybe I got to start again my server for him to understand that I have an index
page right now.
And there we go. I got my index page display. And if I get to slash events, I got
my events page.
All right. So it's really cool. Let's try to create a new page. And let's say that
is going to be
my and dash profile.view. Okay. And here I'm going just to copy paste the code that
I have
there. I'm going to close all of this. And I'm going to type my profile. See that
it's also
working. How cool is that? Okay. Let's remove this my profile.view. And let's
create instead of
events.view a folder called events. And now we've got a problem because we've got
this event.view
and events folder there. So what we can do is to move this event.view here. And I
can rename this
index.view. And let's say that I want to create a file inside my events folder
which relates to
another route. Is that possible? Yes, it's possible. And it's going to create the
full URL for us.
So let's say that we've got an event. And here I'm going to have a profile.view,
the profile of the
event, let's say. So I'm going to have a template tag, div, profile event there.
I'm going to save.
And when I get back and I type slash profile, okay, because I'm in the events
folder and there
we go, we access to the profile event page. How cool is that? It's amazing because
we can create
a lot of routes like this. And of course, if I wanted to create a new folder called
profile and
inside I would like to add a new view and which will be indexed inside, it could
work. So you see,
you can create really nested routes and with this file routing system inside pages,
next,
we'll totally understand what you are trying to do and we'll build for you all the
paths that you
need. Let's say now that in event, I would like to have an ID actually that I would
catch through
my route. You can do that with brackets. So here I'm going to type ID between
brackets.view exactly
like we would do in Vue.js. So I'm going to type template there and I'm going to
type div and
actually I'm going to have event ID and here, of course, I would open my double
curly brackets
and inside I would try to access to my route, params.id exactly like I would do in
Vue.js.
Okay. This dollar route is the object related to the current route. And here we're
going to catch
the ID between the curly bracket, between the brackets, sorry, that we got in our
Vue file.
When I go to the page, event ID 12, for instance, there we go. We catch 12 as an
element provided
into the params. Okay. It could be anything. It could be a very long number. It
could be Guillaume,
for instance, whatever. There we go. We can catch it this way. So when you want to
make dynamic routes,
you can use those brackets and put inside the parameter that you want to catch.
And it's going to pass immediately through the route this parameter for you.
Oh, if you want to catch this parameter inside your script, so here I'm going to
open a script.
With Nux, we got auto import everywhere. So here we got available a method called
use route.
So I'm going to create a new variable and here I'm going to use route, the method
that helped
me to access to the route. So I'm going to console log this route. And I'm going to
get back,
open my console. And what we see is that we got the route as a proxy object. What I
can do is
to type route dot params, exactly what I would do inside my template. And here,
there we go.
We see that it catch actually the ID of my route. So I get route dot params dot ID.
And this method use route is available everywhere in the Nux application. And you
will see when
we get more deep into the course, everywhere in the Nux application, you have a lot
of methods
like this that are auto imported everywhere you need them. You earn a lot of time
by doing this.
This is a good timing to show you another method that is very useful provided by
Nux.
Exactly like next.js, if you know next.js, you have the context available. Nux also
got the context
that is available. What you can use actually is the use Nux app function. Here I'm
going to remove
this. I'm going to type const Nux is equal to use Nux app. Use Nux app is actually
a function that
going to console log Nux. I'm going to get back. I'm going to update. And look at
that. We've got
an object which is big and contains a lot of method and data. And if we look a bit
closer to it,
we see that we got access to what we call a context. This is actually the context
of your
current application. So here you got a function called use head. We're going to see
that later.
We got view app that gives us access to all our view application with the instance,
et cetera,
et cetera. And all of these will help us to deal with some operation everywhere in
the application
when we need to. And on the official documentation, we've got a good definition of
what is use Nux app.
Use Nux app is a built-in composable that provides a way to access shared runtime
context
of Nux, which is available on both client and server side. It helps you to access
the view
instance app, runtime hooks, runtime config variable, and internal state such as
SSR context
and payload. Use Nux app will be very useful when you will create your own Nux
application.
You may need this context very, very often. Don't forget about it. Let's finish now
to talk about
the navigation. If I get back to my app.view here, let's say that I want to create
a header.
And here it's going to be a header with a list of elements. So here I'm going to
have a list.
And inside this list, I would like to have a link that pushes to the homepage. What
I can use
is Nux link. And Nux link, actually, it's a built-in component that helps you to
push to
the route that you want. So here I want to push to home. So I'm going to type
slash. And here
it's going to be home. And then let's say that I want to push to events. So I'm
going to type
slash events. When I get back here up there, I got two buttons. So now it appears
like a text.
But when I click on home, I go on home. Then I click on the events. I go on the
events.
Okay. So use Nux link. When you want to create a link that push to a route. And
when you want to
system to deal with the routes. We don't need to create a route folder. We don't
need to import
Nux itself is built around this file routing system. And later, you will need to
deal with
authentication and deal with what we call middleware. If you need to prevent the
entry on a page,
depending on the authentication, for instance, what you will need to do is to watch
the course
about middleware. Because within Nux context, actually, we can deal with middleware
that
prevent some actions depending on the user interface and depending on the user
entry URL.
It's time to talk about the components. With Nux 3, we got a feature called auto
import.
Which basically means that every component are available everywhere in the
application
because it's auto imported. So if we look at the documentation, it's written that
most components
are reusable piece of user interface. You can create these components in the
components
directory and they will be automatically available across your application without
having to
need the component to import it everywhere we need it. We can also go on the
main.js file
and say, actually, to the Vue application to use the component and we can import it
everywhere also.
It's a kind of auto import. However, with Nux, we don't need to do all of this.
And that's really amazing because we save a lot of time. So we are going to create
a folder and
here I'm going to close all of this. We're going to create a folder called
components.
Okay. Components. And here inside this folder, I'm going to create a first
component called
alert.vue. Okay. And this component is basically taking a div. This is an alert
component. Okay.
I'm going to add some style to it. So I'm going to be a bg green 500. It's going to
be rounded
px2py1 and text y. There we go. And maybe a bit of margin button. All right. We've
got this component
and right now we've got our app running there, an index page. I put the background
in black to have
a bit of more effect. And now I want to use this component alert in my index page.
So I go on my
index page. And what we used to do before is to go to script. And then we would say
basically
import alert from blah, blah, blah. We don't need to do that anymore. We can
directly say, hey,
here I want my component alert. Let's get back to the app. And suddenly we've got
our component
available. And that's amazing. That's why I love Nuxt. With Nuxt, we save time. So
how does it work?
Basically, it works like exactly pages with the file routing system. It's based on
the name of
the file and it's based on the level of the current file. So if I create another
component, let's say
that it's going to be header.view. And here I'm going to type this setup and I'm
going to put
header here. If I go to my app.view and on top of that, I'm going to type header
because it's the
name of the file. What's going to happen is that it's going to look for header as a
component,
as the file coming from the folder component. So you have to create this folder
component to tell
Nuxt, hey, I'm looking for a component. And this component is supposed to be in the
component
folder. So the component directory is playing a very important role in the Nuxt
application.
It's just the place where you're going to put all your interface pieces. So if we
want to create a
deeper component tree, actually, what we could do here is to create, for instance,
let's create a folder and profile. In there, what I can do is to type also
index.view. I'm going to
type profile component. I'm going to close all of this and get back into my
index.view. And down
there, I'm going to type profile. And when I'm going to type profile here, it will
understand
that he has to look for the profile. And here he found a folder and then
index.view. So he
it's going to be profile header. How can I import this header here inside my index?
What you have
got to do is to come from the parent to the children. So we've got profile at
first. So I'm
going to type profile. Then I'm going to type header because my component is
supposed to be
in the header folder. So from component, I want to look to profile. Then I want to
look to header.
And inside header, I got this index.view. So I'm going to type profile header. And
if I get back
of it, I'm going to say that here it's going to be the main page. Now I'm going to
open my console.
And inside my console, I'm going to inspect. And look at this. I got a first div,
which is
ID next. And inside of it, I got the root of my application. And what do I get? I
got a div
called header. We already imported it, but we didn't put the class header. So if I
go there
and I put the class header, we will understand that this is the header we are
talking about.
Okay, header. And then we got the main page. Because remember, in app, we have got
the
header. Then we're supposed to have the current page display. So we've got actually
main.
And then we've got our alert. So we didn't put alert. But if I go there and I put
alert,
it will work this way. There we go. So we got the alert component. Then we got the
profile.
And then we got the profile header. So you can go really deep like this. You can go
really deep by
creating component this way. And let's say that in my header, I would have an
avatar.view.
Okay? Here, I'm going to put class. And again, here on VS Code, I get the pass
profile header
to import this avatar inside my profile. What can I do? Well, actually, it works
exactly the same
everywhere. Depending on where you are, you just need to always start by the
component root.
So here, what is the component I want to import? The component I want to import,
it's avatar from header from profile. So I need to start by profile. Then I need to
look to header.
Then I need to look to avatar. And this is the component that has been created
previously.
I went to profile, then header, then avatar. And I've created this profile header
avatar.
And when I get back to the app, there we go. I got my profile avatar just after
inside the profile
header. It's a bit confusing when you get a lot of files like this. If I go to my
index page,
which is supposed to have profile, and I remove this, I get nothing. And if I want
to use the
avatar that is in the profile header avatar, what I can type, it's always the same.
I can
always import all those elements depending on their roots. In this example, I made
in purpose
something complicated. I created several folders with several files inside because
I wanted to
show you that you can go from a simple organization to a complicated organization
and to retrieve
actually the path of the component because you are not importing them anymore. And
you are using the
auto import feature of Nuxt. You will need to understand how to catch those levels.
And the
easiest way, as I said to you, is to come from the parent, then going to the
children until the
element you want to catch. What we notice with Nuxt3 and the components, it's that
this system
helps us to not importing everywhere our components. And it gives us also the
ability
to call components everywhere we want dynamically. However, be safe. When you are
creating your
components architecture, try to be simple. Try to be easy. Do not create really
deep folder and deep
files because otherwise you will have very long name at the end. If we get back
there, for instance,
we get a profile header avatar, it's a very long name, okay? You don't want at the
end to have
very, very long name because the readability and the developer experience will
decrease.
So this system is good. Nuxt made something great with this auto import. However,
be careful on the
behavior of our app depending on the authentication, for instance, if we are logged
in or logged out.
For that, we can use what we call layouts. And, of course, Nuxt.js helps us to deal
with layouts.
So right now I got my main page and if I get back, I just got this page here,
index.view,
that is created and it's totally empty. And let's say that I want to create first a
default layout
for this page. What I'm going to do is first I'm going to create a layout folder.
Inside this
And we will see later that in our page, we will be able to declare what layout we
want to use
depending on the situation, depending on what layout you want to display, actually.
So here I'm
going to create a template. And in this template, I'm just going to create a first
div. And this
div is going to be class and I'm going to call that default layout this way, okay?
Just for the
example. Then what I'm going to write is just a p and I'm going to type default
layout. So we will
see that we are in the default layout. What I need to do now is to specify that
here I want to put
the data. I want to put the pages. I want to just display the current vision on
what I want to
display. So I need to use the built-in component slot. Slot here will receive
actually a page
which is index.there. So once I have done this, let's get back to my app. Let's
refresh. And there
we go. We see that without writing anything on my index.view, I got this default
layout that is
display. And if I open here my elements there, my console, I got the default layout
that is apply.
And we see that the page is a child of the default layout, all right? So we created
our first layout.
And if I apply some class, like, for instance, text-wide bgslate900 and hscreen for
this one,
we will see that my style will be applied on the whole layout. So on all the
children down there.
So to create a layout, you use a slot. All right. Now let's try to create another
layout which will
be a custom one. So here in layout, I type custom.view. And actually what I can do
is just copy
pasting this custom layout. And instead I'm going to call it custom layout. And
here is going to be
custom layout. Again, we need the built-in component slot in order to display the
content we want to
display. So now I've got this. I want to create another page because default is for
all the pages
that are not asking for any other layout. But now I'm going to create another page.
And let's say
that this one will be, for instance, custom.view. Exactly the same name as the
layout, but you're
not obliged. It could be Evans or whatever. Okay? So now we set this. We have to
create another page.
So I'm just going to grab this one. It's going to be custom page. And here I'm
going to type
custom page. All right. The thing is now if I go on slash custom, so with my
router, you know that
my default layout. And this is normal because I didn't specify any layout to use.
When you want
to specify a layout to use, in your script here, you are going to say that you want
to use this
layout on this custom page. All right? So what you need to use as a method is the
define page
meta. Define page meta is a function available everywhere in your next application
that you can
I'm going to use layout. And in there, I'm going to use the name of the layout that
I'm going to use.
So you understood now that I want to use custom. Okay. I specified here on the
custom.view page
that I want to use the custom layout. Now I'm going to close all of this and just
open here
my custom.view. Now let's get back to the page and let's see if we get our custom
layout.
So when I get back, I get finally my custom layout. So back in the layout, I'm
going to
change just the color. Let's say that we were going to have a background blue.
There we go. I
got a background blue. Now I'm going to get back on the main page. And we see now
that I switch
from a layout to another one. So if I get back to custom, there we go. We've got
another layout.
So you understand now that we can use this layouts folder and we can create new
layout
inside this folder, they will be automatically registered with the name. And after
in the pages,
you will be able to call this layout through the define page meta method.
When you want to store style sheets, images, or font, you usually use the assets
folder.
But with next, we get two directories that can handle these assets. These two
directories are
public and of course assets. Previously, we created an assets directory to put our
main.scss.
But me, I added two images there to show you how we can use assets to fetch our
images.
But first, let's have a quick look on the documentation and let's have an
explanation
on difference between public and assets. The public directory content is served at
the server
root as is. The assets directory contains by convention every assets that you want
the build
tool to process. So what is the difference between public and assets? That's the
main question here.
Why do we get two different folders? And that's maybe why you are watching this
video,
because it's a bit confusing to have two different folders that we could use
actually
to store our images, font, or et cetera, et cetera. Let's start by explaining the
assets directory.
Let's have a look on the documentation. Next, use a webpack to build and bundle
your application.
This is the tool that basically bundles your app. The main function of these build
tools is to
process JavaScript file, but they can be extended through plugin for vits or
loaders for webpack
to process other kinds of assets like style sheet, font, or SVG. This step
transformed the original
file mainly for performance or caching purpose. So it is clear that the assets
directory is
processing an additional step to your style sheet or your image at the bundle
actually.
So here, this step is improving the performance of our files, and also it's working
on caching.
By convention, Nuxt uses the assets directory to store this file, but there is no
auto scan
functionality for this directory, and you can use any other name for it, which
means that Nuxt is
not watching at assets. It's just a fixed, a static repository there that is here
just for the dev,
and there is no auto scan functionality, so it means that Nuxt is not watching to
it.
So you can name it the name you want. Here, basically, it's assets. Let's take an
example.
Here, I got my app running, and in assets, I added two images. So what I can do is
to go on my main
page, which is index, all right? And here in index, what I could do is to import
this image.
So I can take this example down there, and I'm going to add it just after my LO
Nuxt,
which we can actually put there, LO Nuxt 3. There we go. And I'm going to catch my
image called
1.gpg. I'm going to remove this alt, this useless alt, and there we go. And now I
get back to my app.
I got my image that is display. So this is the first way of displaying an image,
and of course, after that, I could have had some CSS to change the size. Let's try
to display the
second image also. There we go. I got my second image that is displayed there. All
right. This
is the first way. Another way, instead of always using this pass, what we could do
is to use an
alias. So I'm going to get back on nux.config.js, and remember, I have created this
alias previously.
This was the whole way to resolve pass, because now we can use root dir and source
dir with nux,
so I can remove this one, and I could put, for instance, assets. Okay. And here I
can type
slash, and I can use root dir. There we go. Here, root dir, and I can close it.
Here, there's a mistake.
I can close it with assets. Now I did this. What I can do directly, instead of
having the wave that
I got here, I can use at, and at assets will play the exact same role as the wave
and will retrieve
for me directly in the assets folder the image. Of course, if I have a folder, I
have to follow the
pass to this folder, and when I get back, it's also working. This is the second way
of using the pass,
and, of course, it's very useful. Now let's talk about the public directory. We see
that here I
got a folder assets and one GPG file. If I want to access this image, what I could
do is assets.GPG,
but if I do that, of course, I got a 404, because here nux.js is not serving this
folder. Remember,
it says down there that nux doesn't auto scan and doesn't take in order this folder
into its build.
with no process at all, because assets is processing, but public here is not
processing,
we can use the public folder. Here, the public directory is used as a public server
for static
assets, all right? Public server for static assets. You're going to put the image
into the public
folder, and it will stay as it is. There will be no compression, there will be no
processing,
nothing else, no resizing, it will stay as it is. The same for style sheet, the
same for any other
file that you will put in there. You can get a file in the public directory from
your application
code or from a browser by the root URL slash. Let's try. Now, I'm going to create a
new folder
at the root, which will be public, and I'm going to move my two images there into
the public folder,
and I'm going to try to access it. Back in my app, I type the name of my image as a
URL,
and there we go. I got my image available exactly like if I would take it from a
server,
and as you look at it, as you look at it, it's directly available into my URL, but
there is no
preprocessing of the image. This image will be available directly like this, and
there will be
slash. So here, instead of having all of this, I can just put the slash and here
the two, so I'm
going to get back on the app, and there we go. Slash will look directly into the
public folder,
which is very useful if you want to fetch another file like this. You can use
directly the public
folder, but remember, public means that it's public, so it's available on the app
all the time. So you
got to be careful if you want to store files or elements that you don't want to
share. Don't put
it into the public folder. Put them into the assets folder. By using SVG as icons,
you might ask
yourself how to do it with assets and public folder. Well, actually, the thing is
that with SVG,
you would have to use a plugin for VIT to load them, and there is one called VIT
SVG loader that
helps you actually to import the SVG from, for instance, a public or assets folder
and to render
them directly like a component. So here you get this package that is available, and
the only thing
that you would need to do is to go on your VIT config.js, and if you don't have it,
you have to
create it, and then you give the plugin a VIT or SVG loader, all right? So you can
use a third part
plugin for next to load your SVG. However, you know that I like to give you the
best tips
to develop faster and efficiently in Vue.js, and if you want to, and especially
next,
and if you want to use SVG, my advice would be to go on icon.gs.org. And the thing
is that
So let me give you an example. We are going to catch an icon. So here I'm going to
look at it,
and you will see that what we can do can be very cool. So here, if I type bell, and
let's say that
I'm looking for a bell icon in SVG, basically, let's say that I'm going to take
this one,
you see that on this website, on icon.gs.org, I can download SVG as components.
And here we see that I get plenty of other options. I can also do it in React,
Svelte. I can download them directly. What I can do if I click here on component
view,
I can just come back, go on my component, and here I'm going to create a folder
called icons.
And in icons, I'm going to create a bell.vue. And I'm going to copy paste, and
directly,
I got my SVG that is appearing here. So let's say that now I want to catch,
so I'm going to remove this image. I want to use my SVG icon, which is in my.vue
file.
How can I do it? Exactly. Like I explained to you for the components. Listen, I can
simply call
icons bell. And here icons bell is going to call in the component folder icons and
bell. Now it's
done. Let's get back to our application. And there we go. We've got our SVG that
appears this way.
It's way faster than using plugins that we can add to our configuration. This was
my tips.
When you want to use icons, go on icon.gs.org and use them directly as components.
View free introduced to us the new concept of composables. If you already coded
React application
or Next.js application, you might know what are hooks. Well, basically, it's
exactly the same as
composables. However, with the view composition API introduced by view free, the
idea is to split
the code logic into several files instead of having the same logic everywhere
mixed.
Why we do that? Because it makes the code lighter, but also because it helps us to
debug faster and
to have some code cleaner. So we created in view free the composables in order to
separate some
code logic. So let's have an example because we need something concrete. Here I got
two views.
I got index.view and I got profile.view. And let's say that in index.view, I would
have a function
called say hello with just console log hello. There we go. All right. And I want to
trigger
this function every time index.view will be built. So back in my app, I open and
there we go. I got
hello that is console log. Now, let's say that I want to have the same function
triggered in my
profile.view. Well, it's a big dump because I got the same piece of code written in
two different
place. And here the thing is that it's two different functions, even if they got
the same name.
They got the same name, so it means that they are supposed to do the same thing,
okay? But they have two declarations in two places. And that could be a problem
because
one could console log hello and the other one could console log goodbye. And that's
a problem
here because we wish that say hello could do the same thing. To solve that problem,
we could create
a composeables that will contain our say hello function. So here I'm going to
create a new folder
and this folder is going to be called composeables. And now you understood Nux 3.
Auto import is the
main feature. Of course, Nux 3 will auto import all our composeables. So the
convention says that
with view 3, we should name the composeables with a use before. So let's say that
here we are going
to call that use utils.ts. Here what we're going to do, we are going to create a
const, okay,
called use utils that we are going to export. And this would be a function. Okay,
so let's get back
at our say hello. Let's say that in our function we would have this say hello
there. And now what
we want to do, we want to return say hello. Now I get this file called use utils
that I could use
everywhere in my app because I have the auto import feature made by Nux 3. So
instead of
having this declaration there, what I can do is just destructure, okay, my use
utils. And use utils
come from where? It comes from this file composeables. So Nux 3 understands that
every file that is
there as a function and is going to record this function. And here the function
that we have is,
of course, use utils. So I got use utils and what I need to import is say hello.
And now I got my
say hello there that I can trigger. Of course, I can do exactly the same there. And
now I don't
get the problem that I have two different declarations. So here I can put hello
from
use utils. Back in my update, we see that I got hello from use utils. So I really
encourage you
to work as much as possible with composeables. And now you understood that we can,
you don't
need to import, okay, with Vue 3 you would have to do this. You will have import
from
add composeables, et cetera, et cetera. You can have the big benefit of the auto
import
of the composeables for Nux 3. And I really encourage you to gather all the
business logic
into composeables because it's easier to read, easier to debug, and it doesn't make
your code
base heavier. It's a very good timing to talk about a very useful library that a
lot of Vue
and Nux developers are using. This library is called Vue use. Vue use has been
created by
Anthony Fu. He's really known in the Vue community. And there's a lot of other
developers that help
him. But basically this Vue use library is working a bit like composeables. When
you install this
library, you get tons of methods that helps you to develop faster and that improve
your developer
experience. Most of the time, if you would need to detect, if you click outside,
you would go into
your composeables and you would click a function called const on click outside.
Okay? That's really
basic. A lot of developers are doing this all the time. Well, the thing is that if
you install Vue
use, you don't need to do that. All you would need to do is to import click outside
coming from the
Vue use library. So as you see, you get some examples. And it shows that you will
save a lot
of time if you use this kind of library instead of creating your own function. And
at the same time,
think about something. The Vue use core team actually worked on many functions.
Look at this.
They thought about everything. So don't think that you could do better than an open
source community
that is working on that all the time. The code quality of this library is
tremendous. It's
amazing. So do not waste your time writing function. And here you get a lot of
examples.
You may have a trouble and this trouble could be certainly solved by a function
there.
So I really encourage you to go on Vue use and to install this library to use it.
If you code it in Nux2, you might be familiar with the concept of plugins. Let me
give you an
example. Let's say that before you launch your application, you want to trigger
some JavaScript.
Well, actually, it's not really before you launch it. But it's at a certain time
that you want to
trigger some function. What you can do is to use plugins. Also, let's say that you
would like to
have a directive or some kind of function available everywhere in your app. And you
don't want to use
a composable to put this function and import it. You just would like to click. You
would just like
to have a Nux app dot something to trigger your function. Well, what you are
looking for are
plugins. On the official documentation, we can read that Nux automatically needs
the files in
your plugin directory and loads them at the creation of the Vue application. So
basically,
what you need to do is to create again, and it's always the same logic actually.
And this is why
I love Nux. I can create my plugins folder. And inside, I will create a my plugin
dot ts.
So let's create this first plugin, my plugin dot ts. And there we go. The main
difference
is that those plugins can be called at the initiation of your Nux application. So I
get
my plugin dot ts. And if I go down, I see that I need to type export default define
Nux plugin.
Let's go let's type export default, define Nux plugin. And here as an argument, I
can
type the Nux app. Because here at the beginning, I will have my context available.
So let's console
log this Nux app that we already saw before. And there we go. Now I did this, I can
go back to my
app and try to trigger again. And look at that. What I have is that before my
composable function
that says hello from UCTL, I have my Nux app context available. However, in Nux, if
we are
using plugin, it's because most of the time, we would like to have some directive
or to have some
function that we could trigger everywhere. Like I said, at the beginning of this
course. In order
key will tell actually to Nux, hey, record this as a function or directive list
because it's an
object that will be available everywhere in my app. So let's create our own
directive. And here
is going to be exactly a bit like this example, I guess. So I'm going to get back
there. And what
I'm going to do, I'm going to return an object. And in this object, I'm going to
return provide.
And provide here will wait for something. Say hello. Okay. Say hello. I got say
hello, which
actually will take a message, which would be a type string. And it will console
log. Okay. My
message. So I got hello message. There we go. Now I've got this. Okay. Now I've got
this. I can go
to my index.view. And I can call my hello function. So how I can do it? Well, it's
really easy to
understand. We see down there that I can import hello from Nux app. I'm going to
import my hello
function, which is here, but actually it's not hello. It's say hello. So say hello
actually will
be available. And if you look at the object, what I got now is a dollar say hello.
So what we're
going to do first, it's a console log, this use Nux app, which will return to me
the context. And
if I click and I look down, I got down there, I got this say hello function. So now
everywhere in
my app, I got this say hello function that is available. What I can do now is to
use this
function, say hello, simply by typing dollar say hello. And here I'm going to put
Guillaume for
instance. And when I get back and I update, there we go. It's working. Often
plugins are used to
inject into the Nux context, all the logic of a certain library. Let me give you an
example for
Firebase. If you would like to have Firebase installed on your Nux application, you
would use
a plugin. Even if there is a module for Firebase that maybe we are going to see
later. As I said to
you, here we got a very good example on the Nux documentation. We can use plugins
for third library.
And here we got the module view gtag, actually, to add Google Analytics tags to
your Nux application.
A last example is to change the view directive. And here we've got another example.
Here we are
going to create a plugin. And we see that we inject again into our view app, inside
the Nux app,
the directive focus. And in this directive focus, we are specifying behavior. So
this is something
else that you can do inside your plugin folder. You could change your directive
directly there
and say from the start of the app, hey, I want to change a behavior and this is
what I want to do.
So in plugins, you can have custom plugins that you create for yourself and that
create
some triggers. You have plugins that are related to modules and you have plugins
that are related
also to directive. Actually, you can create the plugin you want. And that's the
force of Nux.js.
One of the main reasons I moved from View Free to Nux Free, it's because of the
routing system,
but also because of middlewares. Because with Nux Free, what we can use is
middlewares,
those files that will trigger some operation before we switch from root to another
one.
So you understood now that we can deal with authentication with middleware. And I
can say
that with Nux Free, it's so useful. Let's have a quick look on the documentation.
Next, provide a customizable root middleware framework you can use throughout your
application.
The ideal for extracting code that you want to run before navigating to a
particular root.
That's amazing. I don't know if you realize, but that's amazing because we can deal
with several
cases we want to deal with thanks to authentication. There are three kinds of root
middleware,
anonymous or inline root middleware, which are defined directly in the page where
they are used.
So I get back to my app and I'm going to create a folder called middleware. And I'm
going to
create a new file. And let's say that this file is going to be called auth.ts. In
this auth.ts,
I'm going to export default a method called defineNuxed. And here be safe because
what we want to
have is define root middleware. So this method provided by Nuxed help us to catch
several
parameters to and from are from them. So here I'm going to use to, from. Now what
I'm going to do
is to console log this to and this from. All right. So now I got my middleware.
And you probably understood that there's a mistake because I want this middleware
to be
log. And here on the line two and three of my auth.ts, I'm supposed to have defined
a next root
middleware. So on every root, it's supposed to execute all the code there. It's
because here
the global root middleware is supposed to have a global suffix. So what I'm going
to do is to
rename and put here auth.global.ts. Now I get back to the app. I update. And there
we go. We see that
now on this root, I have my two elements that are triggered. The first, it's two.
This is the
root I'm going to and from. This is the root I'm going from. So I'm going to put
slash and I think
I already got a root profile there. And as you see, and I get data from where I
come and where I go.
So it's really useful to use this global actually middleware that can help us to
trigger some
operation. Let's take an example. And let's say that we want to check on every root
of our
application if we are logged in or not. And we would check that with a variable,
okay, is logged
in. Okay. Which will be on false. All right. Well, the thing is that later we will
have a store.
And in this store, we will have some kind of variable like this. So we will be able
to check
the store first to see if we are logged in or not. And then we could take some
decision. But there,
logged in, we would redirect. We would redirect to a login page. And there what we
want to do,
we want to redirect actually to the page we want to go. And this page, we have it
because we have
two. Two is the destination. Two is the destination. So what I can do is console
log my two. All right.
So when I get back there, I update. And actually, I'm going to go exactly there.
Okay. I see that
where I want to go is to the full pass. So what I can do is to use a method that is
written there
called navigate two. Navigate two. And not from two.full pass. If we are logged in,
we say, okay,
you can go to the destination you want to go. Otherwise, if you don't want to, you
have to
navigate two and the page here could be logged in. So this is a quick example on
how we could create
we already saw that when I removed this global, and I'm going to remove this
example, I'm going
to say just console log hello from middleware. There we go. We saw that nothing is
happening
there. So when I update, nothing is happening on my index page. What you can do
also, you can
specify to your page that you want to use this middleware. So here in my page that
I want to
add a middleware to, I can type define page meta. And in this function that we
already saw to define
the layouts, but we can also use to many other things like title, etc. We can say,
hey, I want
to use a middleware. And this middleware is going to be off. Let's check that. And
when we get back,
we see that hello from middleware off. If I go on profile, I don't get this hello
from the middleware.
And what I would need to do is to do exactly the same thing on profile.view. There
is also a
method that you could use, for instance, inside a plugin. And this method is simply
add route
middleware. Well, basically what we could do is to say to our plugin to add a root
middleware,
and we define this by the name of the plugin, then by the function and everything
that you want to
trigger inside of it. And you can specify at the end if you want it to be global or
not. That's
another way of adding a middleware, which is very convenient with Nux3. It's that
you can set up
With Nux3, we can use what we call modules. And actually, we had already this in
Nux2.
Modules are like libraries. You have to install them and add them to your
nux.config.js. Also,
modules are made to simplify your integration and simplify your developer
experience.
These Nux modules are actually running asynchronous when your Nux application is
launched. And these
modules can be created by anyone. They can be published on NPM in order to help
other developers
to save time to help you to develop faster. We've got Tailwind, for instance. And
if we click on
installation command, we've got a prefix called add Nux.js slash Tailwind CSS. It
means that this
module, this specific library, is made only for Nux.js. And with the add Nux.js, we
understand
that we call, actually, the Tailwind version for Nux.js. But what is the main
difference with a
current library? Well, if we get back, we see that here we have a definition called
a supercharge.
So, a module is here to supercharge your Nux project. So, we understand that this
is a plus
that goes directly inside the real lifecycle of Nux. So, let's get down and let's
install,
for instance, a package, a module called Nuxed Content. So, how do we install Nuxed
Content?
Well, and how do we install Nuxed Module most of the time? Well, which is cool is
that we have,
often, a documentation that comes with the module that has been created by the
developer. And that
is really useful because when you click on it, we arrive on a new website, on a new
documentation
that explains to us how to use this specific package. There, I'm going to click on
get started
for Nux content. And we see that I don't got a new project. I want to add my new
project.
So, what I would need to do is to add this, actually, this module by stopping my
server
and just typing yarn add dash dash dev at Nuxed slash content. I'm going to type
enter. And after
the installation, I am able to see that in my list, I got Nuxed Content as a dev
dependency.
So, it's not finished because with Nuxed, what we need to do when we want to use
modules
that are entering inside my Nuxed cycle, actually, my Nuxed context, I need to
specify to my Nuxed
application to use this module. So, what I'm going to do, I'm going to get back and
go on
nuxed.config.ts. And here, I'm going to type modules, which is an array. This array
is waiting
for different modules. And we see here that type 9 proposed me already Axios as a
package or proxy.
But me, I'm going to use Nuxed content. And when I get back, I'm going to type
enter there. There
we go. And now I got Nuxed content. So, I'm going to type yarn dev. And actually,
you will see that
here for this specific package, nothing will have changed. However, if I want to
use Nuxed content,
we see that I have to create a content folder. So, I'm going to type content. And
inside,
And now, with Nuxed content, Nuxed understand that he has to look at content. So,
I'm going to type
lol. And if I want to render this content, I have to use a built-in component
called content doc.
So, I'm going to close this. I'm going to get back. And now, this built-in
component, content
So, I'm going to go on my main page. And inside, instead of having this lol, I'm
going to put
content doc. And when I get back, I get my content. So, as you see, there are many
modules that you
can use. For instance, E18n, which is actually for internationalization. And it's
always working the
same. What you need to do is to install the corresponding package and then to add
it to your
module array inside your Nuxed.config.ts in order to use it. Most of the time, you
will look for a
library to use in Nuxed. Well, before doing that, I highly recommend you to look at
Nuxed modules
because maybe there's already a developer that did work for you and created a
package that will help
need a state management system. What is this exactly? Well, when you have a view
and you declare
some variables inside this view, you have what we call a scope. And these variables
are available
only in that scope. However, sometimes we need to have some kind of state
management to just share,
for instance, the data or variables between components, pages, and everywhere in
your
application. For that, we use a state management system. And of course, with Vue 3,
if you already
coded a Vue 3 application before, you might know Vue X or Piña. But with Nux 3, we
have a new
solution, which is user state. And we are going to look at it right now. Nux 3
provides user state
what does it mean? Later in this course, we are going to look at rendering mode.
And SSR
mean server side rendering. Here, Nux is talking about user state. And user state
is a ref
replacement. So if you don't know ref, it's a new function provided by Vue 3 that
actually will
create for us a proxy variable that will be reactive. If you want to know more, I
highly
recommend you to look at Reactivity in Vue 3. Let's have an example. Here we have a
basic usage
that I'm going just to copy paste. So I get my app there. I'm going to remove all
of this
and use the official example. So when I get back, there we go. We see that when I
click,
which is returning actually a value. All right. That's really interesting. But what
we are looking
for actually is to have some kind of store or state inside our app. So here it is
working. All
right. But here we see that we have shared state. And this might be what you are
looking for.
Go to our composable and let's create a new file called states.ts. By the way, in
the previous course
of composables, I told you that the convention is to use as a prefix for your
composables. It seems
that here in this example, it's not respecting the convention. Here I see export
const there.
I'm going to copy this. All right. And there we go. Now I get this state.ts through
composable
that is injected inside my whole application. And so I get two values available.
Use counter
and use color. And the thing is that here we would like it to work like a state in
ViewX. Why do I
take ViewX as an example? Because if you did next to before, you knew that a folder
store would be
already written by default. And in this store, every store that you would create
would follow
the path of ViewX. So basically, you would have ViewX store that will be auto
imported,
auto injected inside your next content application. Actually, every store that
would be created inside
this store folder would be injected directly into the next context of your
application.
Here we've got an example of a ViewX store. And basically, there's a state, there's
mutation,
there's actions, there's dispatch. All right. But this is for ViewX. In the example
provided by
next3, we see that this use state can work exactly like a store and can return
actually
just an object or a value that could change. So what we want to test? We want to
test that
is this counter will have actually the same value everywhere in my app.
So here, instead of having counter there, I'm going to call use counter, which
actually comes
from my state. Here I get my use counter. And what I want to do, I want to create a
component,
and let's say that we're going to have counter component, counter.view, that would
have exactly
the same code as in my app. Now I've got this, I can create a new div. And next to
it, I'm going
to call my counter. So I will have a double counter. Here what I can do is to put
an ID,
and let's put the ID main. And here I'm going to put another ID, which will be
counter.
When I get back to my app, we see that I got these two different files. I got this
file,
which is the counter. And I got this one, this scope, which is main. I want to be
sure that
my state encounter will also change. So let's click, and we see that actually my
state is changing in
the two components. Here we've got what we call a shared state. We can define
global type safe
states and import them across the application. So the main question would be
Guillaume. Why
we will use a state.ts, that will be actually a composable, instead of using ViewX
or pinya.
That's the question I asked myself also. And I found this very good article on
viewmastery.com,
which is a reference about view, written by Michael Tissen. And this article is
called
Nux3 state management, pinya versus user state. And here Michael is asking the same
question as me.
Do I use Nux3 home state management solution user state? Or should I use Nux3 with
pinya?
Which is better? Well, here is the short answer provided by Michael Tissen.
Pinya is what you get if you keep adding more and more features to user state.
More complex app will benefit from the extra features in pinya. But user state is
better for
small and simple apps. This is the short answer and I think everything is said
there. If you have
a big application and once your user state is heavier, you should use a state
manager like pinya.
Otherwise, if you have a small application, you better use user state. And if you
want to know
more about why we use user state in state of ref, what is state hydrotation, and
what are all the
problems around it, and why to use either user state or ref, I recommend you to
read this article.
Otherwise, we will have to install pinya as a state manager. Because yes, even if I
showed you
this state management system by Nux3, I also want to show you a bit of pinya.
Because yes, for me,
I can't make a course about Nux3 without talking about pinya, which is an amazing
state manager.
So let's have a look. Let's install pinya. And so I'm going to stop my server. And
I'm going to
type yarn add pinya add pinya nux3. So you understood now that this pinya nux3 is a
module
that I'm going to add. And if you want to look at it, you can go on the module page
of Nux3 to find
it. Or otherwise, you go on pinya.vgs.org and you look for NuxGS. So I'm going to
get back to my
nux.config.gs and I'm going to add pinya nux3. There we go. Now what I got is that
I can use the store outside of setup. So I'm going to type yarn dev again. And I'm
going to
create a new folder at the root of my application. And this new folder will be
stores. Actually,
in this folder, what I'm going to put is actually, yeah, my store. They call it my
store. As an
example, my store.gs. So now I need to create my store. So when I get back, I got
an example there.
I got several examples, actually. And what I'm going to do, I'm going to copy paste
this use
counter store. There we go. So how does a store is working? As I said to you, with
pinya, we got
state getters and actions only. All right? So now with the state, we are returning
some value.
And we got getters that are actually like computed function that will return to you
the value when
it's updated. And then we got action. Only the action are supposed to mutate our
store. We've
got another option. We can write our store with the view free way. So here, as you
see, we've got
ref, we've got computed, we've got increment. So when I get back there, I have the
whole way
of doing it. Now I'm going to copy paste and we are going to look quickly at the
difference.
Down there, we have the view free composition API that has been used. And up there,
we have the view
two, which is actually used with the option API. State are replaced by reference
and getters are
replaced by computed properties. I decided to keep it on the view free way. So with
the composition
API, I got my store. I'm going to import my store, which is use counter store. I'm
going to create a
variable called store, which we call actually the counter store. And I want to
console log it. When
I get back to my app, we see that I have the proxy that represent actually my
store. And if you are
using view dev tools, which is actually an extension for Chrome, you can see that
there, we've got access
to our pinna stores and we've got our counter just in here. We see that there are
several ways
of dealing with the state management inside Nuxt free. You can have the user state
through
composables, or you can use pinna, which is a more complete library or module to
help you to deal with
state management across pages and components. Which is brand new with Nuxt free.
It's this
server directory that can help us to create actually a backend and to deliver some
Nuxt automatically scans files inside the server directory, API and server routes,
and also server
middleware directories to register API and server handlers with HMR support. So
what we can see is
that we can use the define event handler. And this handler can directly return JSON
data, a promise,
or use event node.res.n to send a response. All right, let's go directly into the
subject and
let's create a server API folder. So here I'm going to create a new folder at the
root of my
application. I'm going to type server and inside, because I want to follow the
documentation,
I'm going to create an API folder. So I'm going to click on there and here I got an
API folder.
an endpoint. And which is cool is that when we look there, we see that later we
will be able to
fetch, okay, we will be able to fetch a root slash API slash LO if we are creating
a LO.ts file.
So to start, we are going to copy paste this code and I'm going to create a simple
LO.ts file.
And there we go. So my server is running. And we see that in my console, there is
this
nitro build in 400 milliseconds. What is this nitro? We are going to see that just
after.
So I'm going to get back there and I'm going to open my application. So my
application is there.
And if I type slash API slash LO, I'm supposed, okay, I'm supposed to have an
endpoint that
responds to me, actually what we wrote before. And when I type this, there we go.
So now we see that
our NuxJS application, it's not only about frontend, it's also about backend. We
have an endpoint that
is available and here that is answering to us a JSON object. So Nux now has a role
of a frontend
framework but also of a backend framework. Actually, it was already the case
before. But now we see
that we can create our own endpoints and to do some backend. So let's just console
log this
event object that we've got there. So I'm going to open this. I'm going to get back
and I'm going to
type again on the endpoint. And we see here that we've got an h3 event object with
a context nitro
and a big node object. And we can see there that we've got everything that we need
to handle this
node call. So and we got also a res with a server response, et cetera, et cetera.
So we can see that
here we can catch events going to this API folder and to this API. Actually,
hello.ts
endpoint on our API. Okay. But what is the point to have a backend on my frontend
application?
Well, it can be for many reasons that you would need a backend for your
application.
For instance, if you want to provide some triggers or provide some action that you
would do not on
the frontend side but on the backend side, now NUGGS gives you the opportunity
exactly like NUGGS
because we can do the same with NUGGS. It gives you the opportunity to actually put
some business
logic on the backend side and not on the frontend side. So how does it work? Well,
basically, on the
server where you are going to host your NUGGS application, it will also run the
backend,
and it will provide the operation on the backend side and not on the client side.
If you never did some backend before, I highly recommend you to dive deep into
NUGGS or at least
a little bit to understand how we create backends. It's not that you have to learn
everything about
the backend to handle this part of NUGGS. However, if you want to create some
triggers and some
endpoints, however, it's always good to have some knowledge to start creating
endpoints on a backend
such as this one. If we continue to read the documentation, we see that we can make
some
cull there, and we are using a method with a dollar fetch. However, what is this
dollar fetch?
Well, we are going to see this in the course, dollar fetching. But for now, I'm
just going to
copy this code there, and I'm going to get back to my application. So on the
frontend side,
and I'm going to open my console. And what I'm going to do, I'm going just to copy
paste this
code. So I'm going to get back there. I'm going to go on index. And up there, I
still have my
content dock, which is there. It's okay. What I'm going to do, I'm going to type
await fetch
API hello. So we have a top level await there. So what I'm going to do, I'm going
to type
const response. And I'm going to console log my response. And when I get back,
there we go.
We see that my frontend called my backend automatically. And it called the API
folder
with the endpoint I have created in there. See that in the same application, we can
do
full stack operation. Because we can have a frontend and a backend. So it can be
very useful.
If we continue, we see that down there, we've got a server root option. And it is
written,
file inside the server API are automatically prefixed with API in the root. Yes,
that's what
happened here when I type slash API slash hello, which is the name of my file.
Hello is, of course,
the name of the endpoint. I got an API there in my URL. Maybe I don't want it. So
for having server
roots without API prefix, you can instead put them into server roots directory. So
let's get back.
And at server here, I'm going to create a new folder called roots. And in there,
I'm going
to copy paste my hello.js that I got there. However, I need to change the code of
this file.
So I'm going to get back there. And I'm going to type hello world from roots
folder. I'm going to
save. And now I'm going to get back. And instead of having API hello up there, what
I'm going to
type is just slash hello. And it will work exactly the same. However, the
difference here is that I
didn't return a JSON. I just returned a simple string. If I would like to return a
JSON, I could
do exactly the same as I did in the API folder. So back in my roots folder now, I'm
going to just
open these brackets this way. Hello from roots folder. And I'm going to save. I'm
going to get
back. I'm going to type again. And there we go. I got my JSON there. We just saw
two ways of creating
server endpoint on Node.js. We saw the API folder, which will prefix all your
endpoint with slash
API slash. Otherwise, if you want to create root without the API slash, you can put
your endpoint
inside the roots folder. Your file, they look like they export a default define
event handler method.
And inside, every time you can provide operation, you can trigger actions,
whatever. But every time
you have to return at the end the result of your endpoint. You know me, I try to
give you all the
best practice all the time. When you are creating a file like this, it's creating
actually an endpoint.
And this endpoint will take the name of your file. Well, try to be concise every
time you are going
to create some endpoints. The name of the endpoint should be really logic and
follow some pattern.
Here, what we do, we are creating a hello root. And this root is supposed to have a
method.
The method can be post, get, patch, delete, whatever. So the best practice that I
want to
give you now is to actually always put a suffix at your root. Here we have a root
hello. And the
method is supposed to be get. So I'm going to type get. And now we understood that
actually this
root is supposed to be a get method. So if you are going to try to post to this
root, it's not going
to work because the suffix is now get. When you put just hello.ts, it's like you
are doing anything
you want. So remember, in Node.js, or if you don't know, in Node.js, when you are
creating an app,
you can specify the method by typing app.get, app.post, app.patch, and then you
provide an action.
Here, what it does actually, without putting a suffix, it does an app.all. It means
that it's
going to receive any request depending on the method. So the best way is always to
specify.
Of course, if you get a post, instead of get, you're going to put a post. If you
get a delete,
Now,
previously on the server part, we talked about nitro. Because when we launch our
application
on Next3, if we look at the terminal, we can read that Next is running on nitro.
What is nitro?
Well, actually, nitro, it's a server engine. And actually, on the official
documentation,
we've got some information about nitro. Next3 is powered by a new server engine,
nitro.
running on Node.js, now it took nitro, this new engine, that helped us to make
Next3 running.
Serverless support out of the box, API would support, that we saw already on the
server part.
Automatic code splitting, async loaded chunks, hybrid mode for static plus
serverless site,
and we will see that this hybrid mode is the brand new feature of Next3.
Development server
with hot module reloading. There's also a website for nitro on nitro.ngs.io. And if
we click on
get started, suddenly we see that on the documentation, we recognize what we've got
on
our server part on Next3. We see that we have this method called define event
handler. And we see
that we can create, actually, a backend, a server with nitro. So why Next3 decided
to use nitro?
Nitro. For many reasons, and one of these reasons, it's that we can use the cache
API to cache
elements. Okay? So the thing is that Node.js is really known for its SEO
performance and its
server side rendering mode. We are going to see later the mode. However, now let's
talk a little
bit about how we can cache elements with Next3. Basically, what's going to happen
when we use
SSR is that every time we are requesting a server, the server is going to build the
application and
deliver it to the client. The difference with the SPA mode is that on the SPA mode,
everything is
done on the client side. With the SSR mode and the hybrid mode that we are going to
see later,
we can cache elements, which means that instead of every time there is a request,
our next application has to be built. We cache the element every five minutes, for
instance,
and every five minutes somebody is going to come. It's going to build a cache
version,
and during this five minutes, it's going to deliver the content to the next call.
Also, Nitro provides to us a built-in storage layer that can abstract our file
system or
database to any data source, and that can be very useful, especially if you are
doing some Redis.
We can store some elements when we need them. Then, of course, it is backend, so we
can use
the router and link from Nitro that help us to create some routes and some
endpoints to provide
some operation, which is really funny, and at this point of the course, you already
saw a lot of
auto-import with Next.js. We have also auto-import with Nitro. What I like,
especially about Nitro
also, is that there is a deployment documentation that helps you to deploy, for
instance, on Netlify,
and that helps you to deploy Nitro if you want to use it also separately from
Next.js.
So, it was necessary for me to talk about Nitro to have a quick presentation of it,
because this course is not about Nitro, it's about Next. But if you want to do some
backend
on the Next side, you might want to focus on Nitro, and especially to go, for
instance,
what the organization that created Nitro, but not also Nitro, some other methods
that are used
inside Next.js 3. This is probably the most important lesson of this whole course
about
Next, and this is probably the one you were waiting for, because Next.js is really
known
for its options about rendering. So, previously in the lessons, I was talking about
how you can
render differently your applications, and it's not related to Next.js. However,
Next.js is providing
many options that are very useful when you want to take care about the SEO of your
application,
for instance. So, for this lesson, we are going to look at two documentation, the
old one,
the one about Next 2, and then we are going to switch to the Next 3 to see the
difference.
What is rendering? Well, we can look at a good definition about rendering on the
new
documentation, and we can see that here it's written, both the browser and server
can interpret
JavaScript code to render VGS component into HTML elements. So, we can see that we
can render
our application from VGS component into HTML element on the client side and on the
server side.
This step is called rendering. Next supports both client side and universal
rendering.
The two approaches have pros and cons that we will cover in this section. But
before,
let's get back to the old documentation, and let's look at how it was written
before.
We talk directly about server-side rendering, SSR, and static site. Server-side
render sites
are rendered on the server each time the user requests a page, therefore, a server
is needed
to be able to serve the page on each request. Static site, which is the opposite of
SSL,
are very similar to server-side rendered application with the main difference being
that static site that renders that build time. Therefore, no server is needed.
The static sites, they are not billed every time there's a request. They are billed
are billed time when you type and PM run billed, for instance. So, it makes a big
difference
because on static site, it's difficult to fetch the data and build your HTML
document to deliver
it to the browser because when you are fetching the static website, it is already
billed. So,
the data is static there. So, for SEO reasons, what you want to have is that when
the robot
is arriving on your website, you may want to have all the data or the fresh data
already fetched and completed, interpolated everywhere. For that, you will use SSR.
And with Nux2, we had the option SSR true, which we could put on Nux.config.js or
TS.
So, when I go on Nux.config.ts, if I want to put the SSR mode, the only thing that
I have to type
is SSR then true. And from there, my application now will be billed on the server
side. And it
doesn't change something immediately on your application, but this new rendering
mode actually
change a lot of things in your data life cycle. If we look at the new documentation
again,
we have some explanation. Client-side only rendering, out of the box, a traditional
VGS
application is rendered in the browser in the client. So, the computer actually,
not the server
or the phone. Then, VGS generates HTML elements after the browser downloads and
passes all the
JavaScript code. And this schema is explaining it very well. The browser downloads
an HTML document,
then the browser downloads and runs the JavaScript. And the app is rendered and
interactive. This is
the client-side rendering. We see that the JavaScript is not executed. We got pros
and cons
about this technique. The development speed is a pro. When working entirely on the
client side,
we don't have to worry about the server compatibility of the code. For example,
the using browser only API, like the window object. Because, yes, on the server
side rendering,
you don't get any window object. So, that's a problem. But, however, it's a
development
speed feature that is a pro of the client side rendering. It's cheaper. Running a
server are
the cost of infrastructure, and we've got also other problems related to this. And
offline,
because code entirely runs in the browser, it can nicely keep working while the
internet
is unavailable. Which means that with the client side only, when you fetch the
application,
you don't need any more to have actually internet running instead if you are
fetching some data.
But it can work offline, which is amazing. The cons of the client-side rendering is
the
performance. The user has to wait for the browser to download, pass, and run the
JavaScript file.
The server side rendering is faster. And the client side needs actually a good
internet
connection, and it needs also memory to make the work to render the application in
the browser.
With the server side rendering, it's faster. And finally, that's the main topic.
With the client side rendering, we have very bad SEO performances.
And that is maybe why you are watching this video. This is because you would like
to have
good SEO performance on your next application. And with the client side rendering,
this is very bad
to do SEO. Actually, it's useless to try to do SEO because your page is not
rendered at the right
time. And as written here, we can see that as search engine crawlers, so the robot
of Google,
for instance, won't wait for the interface to be fully rendered on their first try
to index the
page. So if you have a SEO problematic on your project, you should do server side
rendering.
Then you get what we call universal rendering. Client side plus server side. Well,
it's actually
the server side rendering. What happens is that when the browser requests a URL
with universal
rendering enabled, the server returns a fully rendered HTML page on the browser. So
as I said
to you, it's going to make the work for you and just send you the page. Whether the
page has been
generated in advance or cached and is rendered on the fly at some point next has
run the JavaScript
this universal rendering is working this way. The fully HTML is sent to the browser
and rendered.
So the work here has been done about all the data completed on the server side.
Then the browser
download and run the JavaScript in background. Then a new step is coming on our
cycle. Because
at that time, we need to get this hydration step complete. And hydration, again,
it's making a
static page interactive in the browser. So when you use SSR, you might have some
errors related to
hydration. It's maybe because you didn't make the static page interactive in the
browser. It
didn't took time to complete, actually, the interactivity of your page. It's a very
common
error that you get when you are doing some SSR. What are the pros and cons of SSR?
Of course,
it's the opposite of the client side. We got a search engine optimization pro,
which is very big.
Universal rendering delivers the entire HTML content to the browser as a classic
server
application. Web crawlers can directly index the page content, because at this
step, we have the
hydration, and then we get also the page content already rendered, which makes
universal rendering
a great choice for any content that you want to index quickly. Then, of course, you
get the
performance. User can get immediate access to the page content, because browser can
display static
content much faster than JavaScript generated one. However, with SSR and universal
mode, we got some
cons. And the first for me, it's the developer constraint that is written there.
Server and browser
environment don't provide the same APIs, and it can be tricky to write code that
can run on both
sides seamlessly. Of course, writing HTML, CSS, Vue.js, React, whatever, on the
client side is
a different behavior than writing it on the server side. When you choose to work on
the server side,
you will encounter maybe errors that you never encountered before, and you will
have to deal
with it. However, the next documentation is very well provided to deal with those
problems.
Also, it's a problem of cost. A server needs to be running in order to render pages
on the fly.
This adds a monthly cost like any traditional server. Of course, because you are
not just
delivering some pages, you are making your server running to make the work instead
of the client's
browser, so it has a cost, of course. However, the server calls are highly reduced
thanks to the
universal rendering with the browser taking over on client side navigation. Why do
we use universal
rendering? Well, for blogs, marketing website, portfolio, e-commerce website, and
marketplace.
Finally, by default, Nuxt uses SSL or universal rendering to provide better user
experience and
performance to optimize search engine indexing. What is new with Nuxt 3 and what
was not in Nuxt 2,
which means here, it's the eBread rendering. eBread rendering allows different
caching rules
per route using root rules and decides how the server should respond to a new
request on a given
URL. So now, basically, with this eBread thing, what we can do is that we can
specify on each page
what strategy we want to choose, either client side, either universal rendering or
server side
rendering. But also, what we can deal with is caching. And as I explained before,
what we can
do is to choose when we want to cache our page and to put an interval between the
time we want to
have fresh data. Caching helps us to deal with this server that will build,
actually, every time
there is a request, your application, and deliver it. Instead of dealing with every
request and
every time building the app, what we can do is to cache our application. And, of
course, this
eBread rendering is possible because of Nitro, the new server engine that powers
Nuxt 3.
So please refer to Nitro to know more about caching. And we can continue on the
root rules.
Because previously, every root page of Nuxt and server must use the same rendering
mode,
client side, and universal. Now, when eBread, we can specify on the root what we
want to use.
Using root rules, you can define rules for a group of Nuxt rules, change rendering
mode,
and assign a cache strategy based on root. So down there, we've got an example with
define
Nuxt config. So you understood that it happens there in our Nuxt.config.ts. So what
I can do
instead of having this SSR true is to have a root rule entry. And in this root rule
entry,
which is an object, I can specify the name of the root, the URL of the root, which
is related there
on a page. And I can specify if I want to use server side rendering or not, if I
want to use
some header, for instance, or if I want to have just static. And I can also work on
headers with
redirect and status code and et cetera, et cetera. So with this root rules, we can
specify with these
options, okay? We can specify which type of rendering we want to use. And that's
the new
thing with Nuxt free, this hybrid possibility that we didn't get before. We had to
put on the
entire application that we want to use SSR or just static. Now we can use both.
When we go on the official documentation, we can see that Nuxt provide use fetch,
use lazy fetch, use async data, and use lazy async data. So we are going to start
by use fetch.
I'm going to put my SSR model files. So like an SPA or a static website. All right.
So now I'm
back. And now my application is not declared as a server side rendering mode for
now. So by default,
Nuxt free is on SSR. But we just removed this SSR mode. So everything is happening
client side for
now. And we are going to start with use fetch. Within your page components and
plugin can use
use fetch to universally fetch from any URL. Universally it means on the server
side or on
the client side. This composable provides a convenient wrapper around user async
data and
fetch. So that's very nice to see. However, what is async data? We are going to see
it after.
And what is fetch? Well, it's actually dollar fetch. Because we know that we know
JS, we have
this method fetch that helps us to fetch some data. And actually it's also
available in JavaScript
regularly. So we have this dollar fetch. And if we go on the API side documentation
of Nuxt,
we can see that the definition of use fetch is these composables provide a
convenient wrapper,
exactly what we read, around async data and fetch dollar fetch. So it's a
combination
between use async data and fetch. And if I click on dollar fetch, we see that
dollar fetch is
actually a function that is globally exposed. And that function comes from a
library called offetch.
And when I click on offetch, I arrive on a repository. And it's called a better
fetch API,
works on node, browsers, and workers. So this fetch here is available on free side,
node, browser,
and workers. And it comes from, of course, NGS, the unified JavaScript tools that
we talked about
before. So use fetch automatically generate a key based on URL and fetch options,
provide type
hints for request URL based on server roots and infer API response type. And down
there, we've got
an example. So we see that at first, our use fetch method can be destructured. And
it can be
destructured in different types. And we can look at this type down there. We've got
data, which
maybe will be the response. And of course, it will be the response. But we got also
pending. And
pending can be a loading state that will be very useful. We got also refresh, which
means that
actually later we will get a function called refresh that when we click on it,
we'll refresh
the call and the data. We've got execute, and we got also error to actually display
the error.
And as options in our fetch, we've got a lot of other elements. But we are going to
come back at
it just after. What I need to do for myself is just to fetch from an API. And
actually,
which is cool with next, is that we can create a server side. So what we got here
is a server
API slash product. And I got this Gson. And you understood now that this root
products will
when I call this endpoint, it will return to me the data from my Gson. So I'm going
to get back,
I'm going to update. And there what I'm going to do, I'm going to go on localhost
slash API slash
products. And there we go. We've got our data there. So the thing is that now on my
index,
what I want to do is to just fetch this endpoint. So what I'm going to do is simply
to put
const data and like it would be a response. Actually, I'm destructuring here, my
response.
I'm going to type use fetch. And here it's going to be API slash products. And what
I want to do,
I want to console log this data. There we go. Let's get back. Let's update. And we
see suddenly that
we have actually a reference. And which is cool is that immediately the data that
is coming from
my API has been turned into a reference value. So what we need to do is to type
data.value,
because there is some value there. And there we go. We see that we've got our data
with our array.
However, it's still a proxy. So that's a bit a problem. What I would need to do is
first,
I'm not going to call it data. However, I'm going to call it products. And what I
would need to do
available, which is amazing. That was for the JavaScript part. However, if I want
to put it
into my template, I will put products there. And what's going to happen there?
Amazing.
What's happening is that we've got our products displayed there. And here, the most
interesting
part of your search is that right now I got this data there. So I can put as an
option here,
I can put as an option a method called transform. With transform, I can say that I
want to change
the model that is returned to my view. What I'm going to do is to open an object
just after my
call here. And of course, later, you may need to put some kind of headers or
anything else.
You can do it there. All the keys that you need to find are in the API docs. And
here we see that
we got many keys such as key, method, query, params, header, lazy, immediate,
watch. Anyway,
what we want is to use transform. And with transform, what I'm going to do is to
access
which gives me the array. And what I want to have immediately is just the array and
not this data
in front of it. So you see, you can use transform to get it. Now, if I go to my
nugs.config.ts,
and I remove this SSR false, and I pass to SSR true, so now I'm on server side
rendering, what
happens is that nothing is happening. Because remember, use fetch can be used on
SSR true or
SSR false. So if you are doing client side, it will work. If you are doing server
side rendering,
it will work also. And you won't see the difference at all. And what we want to do
now, we want to use
use fetch documentation, we see that I get this pending, which is a Boolean. And
what I would like
like to use is another function, which is called use lazy fetch. Because use fetch
is freezing your
application until the moment it receives the data and then it renders the data.
With use lazy fetch,
the old way. Okay. And then here I will have a resolve and reject. I'm just going
to use
resolve that I will not reject. And there I'm going to actually put a set timeout
function.
And this set timeout function will answer after 2,000 milliseconds. And what's
going to happen
is that I'm going to resolve. And what I'm going to resolve is my data. Okay. So
I'm going to save
this. And back in my application, what I'm going to do, I'm going to say, hey, if
it is pending,
I want to have loading. Otherwise, I want to have the products. All right. So we
have a
function which is called use lazy fetch, which is a use fetch, but that is not
freezing our
application. And on the product's end point, we have a promise. So we're going to
wait for some
time, actually 2,000 milliseconds or 2 seconds to render our app. So let's try. I'm
going to update.
And what's happening is that we have a loading during 2,000 milliseconds. And we
have then the
array that is displayed, which is very cool because most of the time with this use
lazy fetch,
we would like to have some kind of skeleton waiting for the app. And it's working
very well.
Let's talk now about use async data. Within our page, components and plugins can
use
use async data to get access to data that resolve asynchronously. And we have a
definition about
the difference between use fetch and use async data. Use fetch receives a URL and
gets that data.
Whereas a user sync data might have more complex logic. Use fetch URL is equivalent
to user sync
URL fetch URL. It's developer experience sugar for most common use case. And down
there, we've
got an example of actually this user sync data, which actually is fetching an
endpoint with a
counter there example and this user sync with this time a key and another URL and a
function
which calls actually dollar fetch. And it returns a promise. And it's using the
callback that you
will put in it. So there we've got this fetch which is there. And we've got this
user sync data. So
the best thing is to put an example. In my endpoint, I'm going to create a new
function,
which actually will wait for a promise on a project count. So we've got a product
count
value up there. And after two milliseconds or two seconds, we are going to actually
increment
this product count. And finally, we are going to return this product count. So when
we are going
to call this slash API slash product, we will wait for 2,000 milliseconds. So we
will need on the
index.view to wait for that call. So it would be asynchronous. And finally, we will
return our
which could be product. And there, what we will need to do is to open this
function. And this is
our callback. We will have the answer of this fetch. And this is this fetch that is
going to
make the call. And remember, this promise will be returned. And then we will get
the data. And we
will have our pending there. So I'm going to get back. I'm going to update. And
what we see is that
there we go. We've got our product count. But there was no pending. Now I know that
my server
is running and that there is this actually every time I fetch this incremental
function, what I
my template a button. And this button will trigger a function that will be called
refresh. And
this refresh function will use another function provided by nux, which is refresh
nux data. And
here, this is where I'm going to use the key of my function. So I got products,
which is there.
So I get back. And when I click, we see that I got finally my loading because it's
already rendered.
And every time I refresh, it's incrementing my product count. Okay. So now I'm
going to use
actually use lazy async data. And it's the same thing as use lazy fetch. Sorry. If
instead of
having an incremental function, we would have a set interval that would be actually
triggered every
second. Now what I have is this use lazy async. However, I don't have any
asynchronous actions
there. So what I can be back is on user sync data. And when I get back and I click
on refresh,
we see that it's been 33. Actually I said product count, but it's actually seconds.
I got 36 seconds,
42 seconds that my server has been running because it's already turning there. And
we've
got this product count incremental every second. We saw that nux 3 is providing to
us several
methods to fetch data. The first method is use fetch. And actually use fetch, which
is a composable,
help us to fetch data universally. So on front side and on the back end side. And
we can fetch
that from any URL. And actually use fetch is a combination between asynchronous
call, which can
be used with the composable user sync data, and dollar fetch, which is coming from
the method
or fetch from the library and the organization of NGS. We also saw that we got many
other options
that we can pass on our fetching composables provided by nux. And this function can
help us
to watch some elements to refresh or to put some others, some keys, method,
queries, and params.
Also nux 3 is working with cache. And we've got a function called clear nux data
that help us to
clear the cache data that we fetch. Because when we use with async data, the key,
we get some cache
that can implies some data that will be not fresh. To refresh the data, you can use
the clear nux
data function. The common problem is to pass the client headers to your API. And
there is a method
provided by nux, which is use request header. And we see here that we can pass
directly the headers
on use fetch. If you have a frontend application, you might want to work on the
SEO. The search
engine optimization is going to help you to be found on Google. And of course, with
nux 3,
we got everything we need to index every page with the right SEO methods that we
can put
inside a built-in composable that is available, which is use head. On the official
documentation,
we see that we got several options to set the SEO methods of our app. And the first
one is to go on
our nux.config.ts. So we can read providing an app.ed property in your
nux.config.ts allows you to
customize the ad for your entire app. This method does not allow you to provide
reactive data. If
you need global reactive data, you can use use head in app.view. So if we go here
on the nux.config.gs,
the first thing that we can do is to open an app object actually. And inside, we
can put a head.
Okay, so here, this head is going to be everywhere in every page of your app. So if
you have several
page later there, it will take the head from here and put it everywhere. So let's
get an example.
So I'm going to put title nux course on YouTube, whatever. I'm going to save this,
look at my
server. So it's running again. And then I come back. And what we see up there is
that I got nux
course on YouTube that is inserted here. If I inspect, and I open my head, we can
see that
suddenly I got my title. So let's continue. Let's say that there I'm going to have
some kind of
description. This is a repository for a course about nux3 for YouTube. So here we
see that
description is not available, of course, because you get a stick to the model of
the head object.
So when I go on here, what I can see is that on app, I can specify many things. And
I can specify
head. Later, we will see the whole configuration. But for now, let's just stick to
this SEO thing.
So I got my head. And we see that actually what I'm trying to put is a meta. So
this description
is supposed to be a meta. And what I can do is to open this meta. Meta is actually
an array.
And inside, we're going to put some objects. And these objects here will get name,
content,
a lot of stuff. So the meta that I want to put, actually, it's actually content.
And here,
this is where my description should be. So I'm going to put name. And then I'm
going to put
description. There we go. He understood. So I'm going to save. Now I'm going to get
back.
I'm going to update. And I'm going to open my head. And I will see if I will get my
description.
we can see that we can add also link, style, script, no script. And finally, we
will find
something like this. And we will get all the SEO provided by default on the
nux.config.ts.
If you got an app where you don't want to put some SEO on pages and just got a
general SEO for
the whole application, you should use this method, go on nux.config.ts. However, if
you don't get
this, let's remove it. And let's doing it page by page. So I'm going to get back to
the first
page, which is index there. And I'm going to get back also to the documentation
there.
So when I get down, and here I had an example that I could use,
again, we already saw that we can put everything on head. I can also use page by
page, this use
add composable. The use add composable function allows you to manage your tags in a
programmatic
reactive way, powered by you view use add. You use again, we saw it before. It's a
combination
actually of many composable that we can use in the library, in the library views.
So what I want
to do, I'm going to do exactly the same. And if we look at this object inside use
head, we can see
that it looks exactly the same as in nux.config.ts. So I'm going to get up there,
I'm going to open
a script as setup. And the thing you should not miss there is that you want to say
that you are
going to use TS, okay, as a lang. So I'm going to use type script. So let's use
this composable,
I'm going to type use add. And inside there, I'm going to put everything that I
need. So just going
to copy paste actually this example. So here I'm going to have a title, and I'm
going to put this
is my homepage for nux course. And I'm going to put as a description page where you
are going to
find everything about this course of nux or okay, then I could put some body
attributes,
then I could put some scripts or links or whatever. Alright, this is done. I have
complete
my methods on my use head. And every time I'm going to go to index, I'm going to
find in the
end, actually, all the content that I have added. So this course is not really
about SEO, but it's
just a good way here that I'm showing you to add some SEO on a specific page, we
would catch this
ID with the use root composable available by view free. And we would catch actually
the
param of this product ID. And then we would inject this product ID directly inside
our
title, for example, right now, I'm on the index.view page. If I go on the
profile.view page,
actually, I want I would like to change the SEO. So again, I'm going to open a
script setup
length, yes, and I'm going to do exactly the same, I'm just going to use add there,
and I'm going to
write my SEO. And there I'm going to write my SEO concerning my page. So here I'm
going to have a
title, which will be profile page. Okay, now, here I'm on index. And if I go on
slash profile,
we see that my SEO methods have changed, of course. So you could work on every
page,
you would like to put SEO on. And of course, if you would not have some SEO, you
could provide it
here inside the use head object. And another thing is that I don't know if you
noticed, but
in the previous example, we had this script. So you could add as a script there,
directly with
the use head, thanks to the use head, the script you would like to launch. So right
now, we've got
a console log Hello World. So when I come back to this index page, we see that I
got my Hello World
that has been triggered here. This is a good way when you want to call a CDN on a
specific page,
instead of putting the CDN link here in nux.config.ts. There is another way to deal
with
SEO. It's by components. Nux provides title, base, no script, style, meta, links,
body,
all those built in components that we can interact directly with your metadata
within your component
template. So let's have a look there, we see that we got just a specific template
there. And we've
got a head component with title just down there. So I'm going to get back in my
index, and I'm going
to remove all of this. And what I'm going to do is inside my homepage, I'm going to
use this head
that I got there. And I'm going to use the title built in component. So this is my
title. For any
reason, you would like to have this component there. So when I get back, and just I
update,
there we go, we see that I have this is my title. And if we continue, we can see
that I can have
some description and some style also. So in my case, it's useless because I already
got tailwind,
but I could have a dynamic title. So I'm going to have my dynamic title. And here,
this is my
get back. And look at that. I got this is my dynamic title. And we saw that the
background was
suddenly green. However, this body green here has been removed by my tailwind. So
we could have
some style. We could have some many other elements related to the built in
components provided by
Nux. As I said to you before, you could have some dynamic data. And here we've got
an example with
ref and reactive. There we've got the example, we could inject the title that we
got there inside
our user head. Of course, if you want to use third party scripts, you can also
inject the scripts,
as we saw in the user head before. And you can say with the body true that you want
them to appear
at the end of your body and not specifically into the template. Remember when we
talked about the
layout, we saw that by page, we could put the layout we would like. And we use
define page
that we can also define the SEO through the define page meta. So what is the
difference between
use head and define page meta? Well, the documentation doesn't explain very well
what's the difference between define page meta and use head. But I guess that if
you really want
to work on SEO, you would use use head and define page meta would be for more less
specific data
that you would put into your metas. The lifecycle hooks, what is it? Nux provides a
powerful hooking
system to expand almost every aspect using hooks. This feature is powered by NGS
hookable. These
hooks are available for Nux module and build context. Here we get the example with
close.
However, if you want to have the list of all the hooks, you can go there in the API
documentation
at advanced. And then you can click here on lifecycle hooks. And suddenly we've got
the list
of every hook that we can use with a description. And it's also telling us the
environment we can
use because sometimes it can be server, sometimes it can be client, etc, etc. The
other way is to
go here inside your nux.config.ts. And you can click on the hook. And suddenly we
can look at
the interface of the next hook. And down there we've got a list actually, which is
exactly the same.
And we see that we've got build before, pages, extend, imports, etc, etc. We've got
a lot of
hooks when we can trigger some operations. So I'm going to pick up a status ready
because it's in
the list. And instead of having this nux that I'm going to catch, I'm going to just
console log the
context because I guess that I got my context already available there. I'm going to
stop and
restart. And I'm supposed to have my context that is console log. And we can see it
there.
So sometimes you would like to create some hooks at certain moments. And you would
like to trigger
some operation for any reason. Well, you can use actually all those hooks that are
available there.
And be safe because some hooks, they are triggered in some environment. Some can be
server and client.
Some can be on the server. Some can be only clients. Another thing that we could do
is to use
those life cycles inside a plugin. So here we've got an example of a plugin that
would be triggered
every time there is a page start. So I'm going to copy paste this. I'm just going
to remove this
hook that I have there. And I'm going to go on my plugin and I got a plugin.ts that
comes back from
a preview score. And here to my context, I would add a new hook on the app created.
And I would like
to console log from plugin. And what we see that I already got hello from plugin.
And here I got
hello from plugin two. I could add some hooks from some plugins. When I would like
to trigger some
treat here, because it's related to Nux but not directly, is the usage of Nuxkit.
Nuxkit is the
library that helps you to create modules. And if you would like to create a module,
also you could
loop through the Nux context and add your own hook inside the module that you would
like to create.
In terms of configuration, Nux give us access to a config file at the root of our
application.
In this config file, we can configure the whole project, but we can also actually
add some modules,
we can add some CSS paths, or we can add some specific configuration related to the
module we
add. Previously, we looked at the Nux.config.ts, and we worked on the CSS paths on
the modules,
and we had it, for instance, post CSS with a config here a file. For instance, I
can give you
a first example. On our project right now, we've got Tailwind CSS. So basically,
with the module
of Tailwind that I didn't use, actually, what I could do is instead of having this
Tailwind.config.js,
I could grab actually this whole object there and add it here in Tailwind CSS
directly here.
That's the purpose of this Nux.config.ts. The idea is that when you are going to
inject a module
to your application, later you will have some configuration file from another
library.
The idea is to never have this config file except the Nux.config.ts, which here
plays the role
actually to the place of the whole configuration of your project. What I just said
concerns only
the modules. However, we have some other configuration that we can add to our
project.
So if we look at the documentation, we see that in this defined Nux config, which
is a
method provided by Nux natively, we can inject this big object. In this big object,
there will
be the whole configuration. When we look at it, we have a lot of options. Which is
interesting is
that we can access this config also, this runtime config. We can access it inside
our DOM by just
using this inside our view. Then later, we've got a lot of configuration. Again,
this app config is
now what I want to do is to show you most of the options that are available
actually in this
configuration file. During this presentation, we are not going to pass on every
configuration key
that you can add. It will be useless. I'm just going to talk about those that are
the most useful
Instead of having a very long pass that you will write by yourself with points and
slash,
you can use those aliases. Here you get the options that says that actually you can
access
through the specific folder that you want with the related pass. Instead of having
slash and root
there, we would add an add, for instance, or we would add assets slash name of the
image.png.
That's a very useful config that you can have. Then we have the app object. You
have the base
URL if you want to change the base URL of your application. You have the build
assets there.
Basically, when you build your application, you have by default this underscore
next.
The folder name for the build assets relative to base URL. You can change it with
build assets
there. You get the CDN URL, an absolute URL to serve the public folder from
production only.
Basically here, if you would like to change, you would type directly CDN URL, blah,
blah, blah,
immediately. You get the head that we already saw in the course on SEO that helps
you to define the
SEO for the global application, which can be actually here a problem because
sometimes you
want to have different SEO data or metas inside every page. Keep alive. That can be
disabled.
Keep alive again. It's when you want to keep alive a component with its data
instead of
just destroying it inside your app. You get the layout transition. We didn't see
the transition.
However, you imagine that irritating from view with Nux, you can do some
transition.
You can turn on false or true your layout transition. Same for the page transition.
You can change the root ID. Here we see that on my div. I got underscore underscore
next.
If I want to change this ID, I can do it with the root ID. So basically I would go
there
and say that for now, the root ID would be Guillaume in, for instance. There's also
the build year
option that helps you to change actually the name of the build directory that you
will have.
So here we got dot next there, and this is the build of your application. It's
actually
what is delivering your application there. If you want to change the name, you can
type build year
and it will create a folder with a new name instead of dot next. You got the debug
option,
which is clearly cool because it logs out when you get a problem or not.
It prints out OX names, timing on the server, logs, everything that is related to
the next app.
If you want to turn it off, you can go on your app and just type here debug false,
and then you will not have the console log in your console.
Then you got the dev server option. If you want to improve your developer
experience and change,
for instance, the host, the HTTP, the port, the URL, you can do that in the dev
server object.
Inside, you just enter those key and you change them.
If you want to customize all the architecture of your project and change the name
of the folder
for any reason, you can use also deer. Inside deer, you can specify where you want
assets to be,
so change the name of assets, the name of layout, middleware, pages, plugin,
public, and static.
It can happen to you that you have extensions that are not resolved by Nuxt and you
have to
specify them inside your nux.config.ts. For instance, there we've got this
extension array
some GraphQL. You would have to declare them inside your nux.config.ts. So
especially there,
what I would do is here, for instance, to say extensions, which would be an array
and it says
CSS, but actually it's not CSS, it would be GraphQL or it would be.gql, for
instance.
And then my Nuxt application would resolve these files with this extension.
Previously,
we already saw the modules, so you can add a module entrance and add your modules
there.
You can also use the root deer option that helps you to define where is your Nuxt
application
and where Nuxt has to look at when it's building your app. If you want to work on
the configuration
of VIT, you can also do it in nux.config.ts. There is a VIT entrance that gives you
all the access
that you need, for instance, to the ears build configuration, the public directory,
the resolve,
the root, the server, all the options related to Vue. And finally, there is a big
set of options
to configure Webpack, because if you are already a front-end developer, you know
that with Webpack,
you will have some configuration that you would do through a webpack.config.ts
file.
One of the most interesting modules provided by the Nuxt community is Nuxt content.
Why?
Why? Let me give you an example. Sometimes you are creating websites,
and on those websites, there's only static content. This static content is just
written
directly in raw on your HTML. Well, and you don't need necessarily to create some
JavaScript
interaction and stuff, you just want to put some static content, such as text,
videos,
photos, or images, whatever. For that, what you would do is just to create an app
and write
in HTML your title, your paragraph, and stuff. However, one of the most interesting
things
is that you could write this content in markdown. And writing it in markdown would
be easier than
writing a whole application in HTML, CSS, and to set it up, etc. Next content is
providing
an amazing solution for that kind of problem. Most of the websites that are written
to be
documentation are static content. Let's take an example. Here we've got this Nuxt
content website
on content.nuxjs.org. And this website is just static content. There's only text
written down
there. So what we would like to do is not to write HTML, but instead to write
markdown.
And maybe sometimes we would like just to write JSON to display some website. We
can do that with
Nuxt content. With the module Nuxt content, we just need to have a folder called
content,
and Nuxt is going to watch our folder and translate our markdown files into HTML
pages.
It will even do the routing between the pages, and you will be able to change from
a page to another
one just by creating the file. You will not need to register any route. You will
not need to do
actually a content website, a static website with Nuxt content. So I'm going to
click on
get started. And down there here I got a command, npx nuxi init content app. So I'm
going to copy
paste this, get back, and I'm going to enter in my folder. There we go. And here
it's going to create
inside this course will be available inside this app. So I'm going to enter into
it. Once I'm into
my project, what I can see again is that it's a very, very light project. There's
only an
app.view with a Nuxt page at the root. I got a page component with a slug, and I
got this content
doc. Content doc is just the routing system of Nuxt content, a built-in component
provided by
Nuxt content that displays all the pages that will be in content. And if I look in
my package.json,
what I can see is that as dev dependencies I get Nuxt, I get Nuxt content, and I
get this
folder called content, and inside I have markdown files. I have about, I get index,
and just let's
run our project, and that's it. We have our website running Nuxt content, and it
says this page
corresponds to the slash root of your website, blah, blah, blah. And these two
pages are rendered
by the pages slug.view. So here we see that we've got a slug, and we've got our
index. So I'm going
to try to go on slash about to see, and there we go. I got this about page, and
actually this about
page is coming from here. So here I can write in markdown. So to write in markdown,
the syntax is
really simple. You can find a lot of websites that we teach you how to write in
markdown. You may
know already markdown because you already wrote some readme by the past, but here I
can write
content, okay? So I'm going to save this, and as you see, immediately, it's
rendered. So why would
we do that instead of creating HTML pages? Well, the thing is that if you are
working on your SEO,
it can be very useful to create a website this way, because the content here will
be rendered
immediately because it's just static content, and there will be no JavaScript that
will run
inside your website. So for SEO purpose, it's amazing to use next content. Also, if
you want
to write some kind of documentation or some kind of blog, you would use that
because it's easier
to write here some content and to use the syntax, for instance, title syntax of
markdown. There we
go. As you see, you could be way faster by writing here in MD file instead of
working in an HTML
file. Let's create a new page. Let's say that we're going to have some kind of new
file called
profile.md, and here I would like this is my profile. Hello, my name is Guillaume.
Okay,
I'm going to save this, and now I'm going to go to a slash profile, and I type
enter,
and immediately my root has been created. So of course, this markdown is really
limited. You
cannot do any JavaScript or very complicated stuff into it. It's not made to create
web application,
really. It's more to create some content. So another thing is that right now my
website is
totally empty. I would like to put some style. I would like to create, actually,
just some design, you know. I would like to add some colors. I would like to add
some style,
to the modules, and what we could do, we could add Tailwind as a module. Instead of
adding it
directly from the Tailwind documentation, what I'm going to do is to install this
Tailwind module.
So I'm going to stop, and I'm going to install Tailwind as a module. Then I will
need to add it
to my modules there. So I'm going to go to my Nux config, and actually Nux content
is working
exactly like any other module. As you see here, we've got Nux content that has been
added,
and we've got Tailwind CSS. So you can either create a Nux content application
through this Nux content NPX init, or you can still add Nux content to your
existing project.
Okay. So I've done this. So now I'm supposed to have Tailwind CSS installed. So now
I'm going to
type yarn dev. There we go. And if I get back to my app, I should have Tailwind
CSS. That is apply.
And there we go. So now I got Tailwind CSS. What I can do is actually to inspect my
markdown file
that has been transformed as an HTML. And we see that here I got an H1, I got a
paragraph, et cetera,
et cetera. So what I can do is to create my own design system. I can right click
there,
create a new folder. I'm going to create an assets. And in this, I'm going to
create a man.scss.
So what I would do is to stop my server and to type npm install sass. And what I
would do
actually is just to type yarn dev. And I will add my sass here, file to my CSS
inside my
nux.config.ts. So I'm going to type at assets main.scss. And I would save that.
Here what I would do is to import from Tailwind my base. And I would target my
layer base,
which is actually the basic layer that I'm using with Tailwind on my application.
And what I would
do, I would say, hey, I want that my H1 would be apply text red 500. That's a color
from Tailwind.
So when I get back, we see suddenly that I got my title there. And exactly it would
do the same on
every page. Okay. So what I could do also is just to put all these contents so I
can get back
to my slug. And here on the main, I could say that I want to put a container emix
auto there.
So I would say, there we go. And what I could do also, I could add some margin on
the top and on
the bottom with MY4. And there we go. So as you see, now I can create my own style
sheet, my own
routing, what I can do is just to use the markdown. So here on About, we see that I
get a link.
Let's go on Index. And let's just remove this. Let's say Home. And let's say that I
want to have
a link that would say, go to profile in with time slash profile. There we go. And I
want to style
my links. So I'm going to go here and say that all links will have, for instance, a
color. So text
till, yes, let's say till 600 and underline, whatever. I'm going to save that. And
there we go.
And when I click, I can go to the page I want with the routing system. If you want
to know
more about Nux content, you can go on the documentation. You can do that with
markdown,
with MDC syntax. You can also work with JSON. As you see here, you can apply some
JSON.
What you would do is work on YAML also. And you can work also on the displaying, on
the rendering.
If you have some questions about some stuff that you would do, you can go here and
look at rendering,
querying, navigation, etc. Everything is provided. A last thing, if you want to add
some SEO to your
page, because now we are working with markdown, what you can do is at the top of
your file,
you can specify, for instance, the title of your page. So this is my Nux content
main page,
whatever. And when you get back here, we see on the top that I got, this is my Nux
content main
page. So if you want to work on some methods, you can add them here on the top. And
which is cool
also with Nux content, it's that it's really easy to deploy. It's really fast,
because it's just
static content that will be built and rendered. We saw that with Nux content, we
can create static
website, and we can, of course, if we want, create some documentation. For this
practical exercise
that I propose you to end my course on Nux, what I would like to do is to create
some kind of
fake API that we would request. And next to it, I would like to create a fake
documentation.
Okay? So to do that, I can do entirely all these steps inside Nux 3, because I can
create my API
with server. But of course, I can also create my documentation with Nux content.
However,
when we start a Nux content project, it's empty. There is no styling, there's
nothing to do.
You have to build your own style. And actually, with Nux, what we can do, we can
add our own
themes. And our themes can be used to give some style to a website. If you look
online,
you will find some themes. And actually, we have one. And this one is used to make
the website of
Nux content. This theme is creating all this styling there. And all this website,
if we look
at it quickly, we will find that this website is using the theme called Docuus.
Docuus, that you
can find at Docuus.dev. It's actually a theme for Nux that helps you to just
install a documentation
website, a simple one, this way. So it's really simple to use, actually. But the
thing is that
you will have a documentation with a sidebar and everything already set up. So you
will
win a lot of time. I'm going to start by installing this theme as a new
application.
At this point, you should use a specific version of Nod. And if possible, the
version 16. So me,
I'm going to look by typing NPM, NVMLS, sorry. And I'm going to use the 16.17.1.
Because the 18,
there might be some bugs. So here, I'm going to say NVM use 16.17.1. There we go.
And now what
I'm going to do, I'm just going to copy paste this to create my project. And there
we go. We
got our Docuus that has been initialized. And if we take a look at it a little bit,
we can see that
it's a bit different. We've got some TS file, renovate.json. There's a bit of
different
configuration here. But actually, it's still using Nux 3, which we can see on the
dev dependencies,
the Nux team Docuus. So here, we've got our content. What we're going to do, we are
going to
launch it right away. So I'm going to type yarn and yarn dev. I got an empty
documentation that
is available with some specification. I can turn it to light and dark. And I got
this get started.
And it's totally empty. And we can start writing a fake documentation there. So if
I get back to
the project, I got my Nux folder with this guide. I got YAML. I got an index, which
is actually the
basic of my page. And then I got a folder. And with the folder, numbers to specify
for my sidebar
on which side are going to be the documentation. Okay. So what we could do at first
is just to
start with our fake API. So here, I'm going to call it actually fake countries API.
Okay.
API. There we go. Documentation. So here on the title here, it's for the meta,
actually,
of your project. So I can go down and put fake countries there. So here, it's
marked down again.
But we see it's a bit different. It's that we got a CTA button where we can put the
get started
code there. And there's the link to go to the guide or the button, secondary
button.
Then also on our snippet, we can put actually some code if we would like to have
some code.
So here, I'm going to write API to fetch any country in the world with its name,
its
ID code, and more information. Okay. So I'm going to save this. And there we go. I
got my title there.
So now what is our API doing? Well, actually, what we would like to do is to have
some endpoints.
So what I'm going to start to do is to create a new folder called server. And in
there,
I'm going to create a subfolder called API because I want to put API as a prefix.
And in there, let's say that I would like to have a first endpoint called random.
And it will be a random endpoint, an endpoint for random countries. So I'm going to
create
my endpoint. So export default, which would be a function. And I'm going to return
a success
true to try this endpoint at first. So I'm going to get back, and then I'm going to
type slash
API slash random. And there we go. Okay. My endpoint is working. That's great.
Now what I want to do, I want to have some data that I would use to actually to
display my country
So I'm going to install it. So I'm going to stop actually my server. And I'm going
to type
yarn had at Dupco. That's the person who made it. Thank you very much. Slash
countries. So I'm
going to type enter. And it's going to install for me this library. There we go. So
I'm going to
start again. And there we go. And what I can do actually is to import the countries
or the country
list from the library. So I'm going to get at the top there. There we go. And I
think country
list should be an array. So for that, I'm going just to console our country list at
first.
And let's look at it. There we go. Yeah, there we go. That's what I thought. We've
got an array
with some countries there. I want that endpoint to be a get. So I'm going to type
random dot get.
Okay. And it's going to change. Okay, that's right. And what I want to answer is
actually
a random country. So I'm going to type random country as an answer. And it's going
to be
country list. And inside the country list is going to be a mat floor, mat random.
Exactly.
Country list dot length. And there we go. So let's get back and let's try actually
our endpoint
again. And when I type enter, there we go. I got jibalta. If I type again, island,
island.
Okay. That's cool. It's working. What I could do now is actually to just create the
documentation
about this endpoint. So I got API slash random. So what I can do is getting back on
my fake
countries API. I'm going to click on get started. And what I'm going to do at first
is not to remove
this get started because I want to keep it. But actually, I'm going to create a in
the guide
actually in the guide section. I'm going to oh, maybe what can I do is to create a
second
folder called endpoints. All right. And if we say nothing is happening here.
Because what I need to
do is to create a deer dot yaml. Deer dot yaml at the root. And I'm going to use
this as an example.
So I'm going to copy paste this title guide. And I need to put a title. So here
API. Let's call it
API. All right. So I'm going to save. Okay. Nothing happens because I need to put
actually my zero
dot index dot end. And this one, let's take the same example as we get there. I'm
going to save.
And there we go. As you see, I got my page that appears there. And that which is
cool is that we
can see that there is a navigation that is automated between the pages. So API. And
this one
is called get started. Let's try to change the title there. So I'm going to remove
this.
And let's say get a random country. And we see now that my title is now appearing
on my sidebar.
So I'm going to get back. And I'm going to type some documentation about it. So
here it's
again marked down. So you can write whatever you want. Endpoint to get a random
country on our
country's list. Okay. So what we could do also is to type some code that we could
put. Here what I
can put is method get. And down there I could put slash API slash random. And I'm
going to save.
And as we see, there we go. We've got our random that is here. Endpoint to get a
random country
on our country list. If you want to know more about creating endpoints with Nitro,
you can go
using it in Nux3, but you can also create regular endpoints with Nitro. So what are
we going to do
now? We are going to create a new endpoint where we're going to post actually a
request with a
string. And we want to find in our area of countries the specific country. So what
I'm
going to do, I'm going to get back to my app. And in the API folder, I'm going to
create a new
folder called countries. And there I'm going to create a new endpoint called
find.post.ts.
Find would be just the endpoint. So it would be actually API slash countries slash
find.
And this endpoint will be a method post. All right? So what I'm going to do, I'm
going to use
the example of Nitro. And it's exactly the same as the random one. The difference
is that I didn't
use the event handler here function. It's exactly the same, but whatever. Okay. So
now we return
user profile. It's going to be an object that we will return at the end. And what
we want to do
actually is to use the country list that we had before. So I'm going to come back
on this. I'm
going to import. Actually, my country list. And there we go. So what I want to do
is to post as a
body. Actually, I'm going to post an object with inside. And there will be, we can
call that
country. Okay? And country will be a string. Okay. So I'm just making those notes
for this course.
And don't take them as a good practice. Most of the time, you have better way to
write comments
in API. This course is not about back end either on API. It's just to show you the
example.
So it will be a string. Country will be a string. And we will catch it through this
event. So what
we're going to do is to create a variable called body. And we want to await for a
function,
a native function of nitro. And this native function is read body. Read body, we
pass the
event to it. And it's going to return for us directly our body as an object. Which
is very
cool. So we will get our country up there. So once I got the country, I can
destructure country
from the body. And here what I can do is to return the countries that we will find
with this string.
So, for instance, here, if I'm going to type France, it's going to return to me
here an array
with countries that correspond to France. So there's two things that I need to do.
I need to
look at how country lists are looking at. And here I get to return countries. It's
not specifically
one country. It's not find one country. It may be several countries. Because we
will see that
our string will match the letters. And in there what I'm going to do, I think I
already know,
but I'm going just to put true for now. And I'm going to look at the list. And
there we go. I
want to match the label. I want to match the label with country. So if it's going
to be Ghana
JavaScript. Then I'm going to filter. And what I want to do is that here I get an
object. And in
this object, I want to match my object.label that we just saw. And I just want to
know if it's going
to include actually country. All right. So we can save this. I'm going to remove
that.
And now I need to post to this endpoint to know if I get some response. To do that,
me, I'm using
actually rapid API. Rapid API helps you to create some actually postman inside your
IDE. And here
especially it's a visual studio code. So here I need to create a new call. And this
new call
actually will be my post. So I'm going to go there. I'm going to post to what? I'm
going to post to
actually HTTP two point slash local host 3000 slash API slash countries. And here
it's
find. Okay. So I'm going to click on Gson. And here I'm going to pass my country.
Okay. And let's say
that we are going to type France. Okay. And when I type send, there we go. We see
that I have my
country that have been found on my endpoint, which is API slash countries slash
find. Okay.
Now let's say that I want to remove some letters on my country down there. Let's
say that I want
just to type fra. It's still going to find France because on my endpoint, I'm just
filtering on
includes the strings. And I'm looking at labels. So I'm going to get back. And if I
remove some
letters, I got more countries that start actually with French, actually French,
Vienna, France,
back and I'm going to click on send here. I got several countries. So these several
countries
are Algeria, American Samoa, and or Angola, Angola, et cetera, et cetera. You're
not obliged to use
rapid API for this course. You can use, for instance, postman it's better. But for
me,
I got this in my VS code. It's faster. Now I have created my endpoint. What I want
to do,
I want to put the documentation to use it. So I'm going to get back there in my
index.
And what I can write here, it's find a country by label. And actually it's going to
be exactly the
same. Find a country by label on our list. It's going to be a post. And this time
it's going to be
countries slash find. And if I save and I get back, I update, we see that there's a
problem.
Because I got my index and it doesn't put here find a country by label. So what I
need to do is
actually to create another page. What I need to do if I want to separate the two
files, I can create
another markdown file, 1.find.md, for instance. And I arrive there with my
explanation. And there
we go. We see that I get a random country, find a country by label, and there we
go.
Of course, this presentation is not very well. I should work more on the design,
on what I want to do. So here we see that we can copy paste the code, which is
amazing.
However, we've got this method get on the top. It should not be here. So I'm going
to remove this
and I get my endpoint. And I'm going to put just endpoint there. So it makes me
think that I have
boss in markdown. I'm sure you get a lot of ways of doing nicer stuff, but that
should be enough.
So I got my endpoint here. And actually, I can remove endpoint. And what I would
like to have
is a response example. So I'm going to take this and remember on my API slash
random,
I have a response. So what I can do is just to type slash API slash random, looking
at response.
And I'm just going to copy paste this as an example. So I'm going to get back
and I'm going to update. Okay. And here in my response, I'm going to put my fake
response.
And there we go. That's an example of a good documentation we could do. So what I'm
going to
do, I'm going to copy paste actually the same model. So I'm going to get back on
find them.
And instead of having this method on the top, I would put method post. Okay. And I
would put,
for instance, a response example down there. And actually I can take back this. I'm
going to
go there and the response that I got. So let's get back on my API call, which I got
here.
Here exactly. Here I got a response and I'm going to put friends. I'm going to type
and there we go.
Now I can copy paste this here and I got some kind of response there and look at
this.
So that's really cool. Really quickly. I succeed to create the base of an API and
actually at the
same time, the base of a documentation. However, if we look closely at what we do,
we put the
endpoint, we put the response, but we didn't put the body. So let's get back on
find a country by
label. And what I'm going to do is on the top of response, I'm going to put a body
example.
So I'm going just to copy paste this. And on the body, of course, I gather pass the
country,
which will be, of course, France. And here what I can specify is that it will be a
string.
Okay. So here I got a string with the body. And that's good. We are good. Another
thing
look first at our endpoint. And we should look at actually we should look at the
countries that
we've got. Okay. So we've got our countries there. And these countries, they should
have a language.
a currency and also to work on the code, capital, or stuff that we want. All right.
with languages. And we suddenly realize that our countries.find, it's a bit weird,
okay,
as an endpoint. Because find would mean anything. And in our documentation, we can
see that we can
find a country by label. Okay. So and our titles are very long also. So if we would
like to do
something more clear, we would have to work on our API endpoint. And we will have
to work on our
names. All right. I improved a bit this documentation. And I created some
endpoints. And let me present
them to you now. So we still have this entry here with this stuff that is useless.
Actually,
I should change it. And it's called fake countries. So I don't know why it's called
fake countries.
I should have put countries because it's still real countries. So when we click on
get started,
we arrive on the guide that I worked on. So basically, I've had a welcome on fake
countries
API. I've had a version, the date, how to use it, and the options that we can have
if we look
at the documentation of docus, actually, we've got some options that we can add,
such as check,
danger, and stuff. That's really interesting. I've added some rules. This API is
free to use.
However, please do not spam or use it more than one hundred times per day.
We'll banish your IP for 30 days if you spam it. Yeah, that's what I wrote. There's
an about
section. And we see here on the right, actually, that we've got a sub content panel
that is really
useful on the actual page. And on my API, I've worked on my endpoints. So I tried
to be very,
very concise and very clear about what the API is doing. So what I did actually,
I've created
an endpoint called get all. And here we've got this endpoint. This is API country
whole. So we
don't need anybody. So what I'm going to do, I'm going to test, actually, on my
localhost decent
point. And there we go. Let's look at this. We have the full file, actually, as a
GS, a decent
file, actually, sorry, about every country and everything we've got on it. That's
really cool.
Okay. That's the endpoint that I've created. And I've kept this model of putting
the method
and a short description and the endpoint and an example of what we can have. So it
can be very
useful if you want to use the flag, the name, the code of whatever. Then I've
worked on the
random one. So as you see now, we've got API slash countries slash the name of the
endpoint that we're going to have. So for all, I get slash all. For random, I put
slash random.
So when we get back to the server, now we've got our server with the API because
there is another
route that I'm going to show you after. And on API, I got a folder countries with
all dot get
because it's a get. And random that it's a get also. And what I'm doing, actually,
when I get
the endpoints there that will be with this API slash countries. So here I'm going
to try my
random endpoint. And there we go. I got a random country there. Then after on the
other methods,
by label, by capital, by currency, these are posts. And on those posts, actually,
I'm returning not Gsons. I'm returning an array. So basically, here we've got
labels. So we're
going to try it. I'm going to try to catch a country by label. So I'm going to get
back there
on my previous post. And I'm going to type HTTP slash slash localhost 3000. Then
with my slash,
so I'm going just to push that this way, I'm going to get back there. And when I
send it,
there we go. I got France, if I try to find United something, for instance, United,
there we go.
And also what I did on my endpoints is that I put some guards. So here I got my
guards on the label.
All right. I did the same with currency. I did the same with capital. So let's try
capital. So I'm
So I'm going to type instead of countries here, capital. And here as capital, I'm
going to pass,
for instance, Washington. And when I'm going to send it, there we go. I got the
countries by
capital, which is amazing. What I can do also is to type by currency. And currency
is interesting,
because here with currency, I will have several other countries. So when I type for
the euro,
I get all the countries of Europe that have the euro as a currency. Let me try to
find a doll for,
ah, no, it's not, yeah, it's working well. It's not doll, it's USD. So there we go.
We see all
the countries that are using USD, for instance. So what I did, it's exactly the
same. I just copied,
paste some code, and it's working very good. If there is no currency, we can see
that we get also
an error, and it's working very well. So now you can go on the documentation and
check all of this.
It was a quick course to teach you how to use Nuxt content and how to use all the
force of Nuxt to
stack application also. It would have worked. However, it would have taken a lot of
time to
create the whole design, actually, the whole template. Instead, using docus helped
us a lot.
So this is a good example on how you could create a business. For instance, if you
would like to
create an API where people could fetch some data, you would have to use a stripe
layer to make people
pay and to be able to use the API. Once they pay, they get a token, and they can
use this token,
and you could do a lot of stuff like this. So this is really not a real
documentation, okay?
This is a start. To end this lesson, I wanted to show you where I found docus.
Actually,
I went on Nuxt team. Here on Nuxt team, what you can see is that you have several
different
teams that you could apply to your Nuxt.js application. So we've got docus, which
is here,
and this is the one that I use that helps us to create a documentation on the fly.
However,
you got some other teams that you could use, and I think in the future, there will
be more and more
teams that will be available under Nuxt 3. Not pretending that I can build a whole
documentation
by myself, and I'm not pretending that I'm an awesome back-end developer, but this
was a good
example to show you how we can use Nuxt and how we can use its power to create a
full documentation
on Netlify or Vercel, and right away, what would happen is that my endpoints would
be available on
the address provided by Netlify and Vercel. And congratulations, you succeed to
create your first
documentation and your first full stack application with Nuxt.js. Thank you very
much for watching this
entire video, I hope it helps you to create a full stack application. See you next
time, bye!