- 00:00:02 welcome to this video where i want to
- 00:00:04 introduce you to
- 00:00:05 next js now what is next js
- 00:00:12 next js is a library for vue.js so let's
- 00:00:17 quickly have a look at this first what
- 00:00:19 is vue.js
- 00:00:20 now i already got a series and a course
- 00:00:22 on that which i strongly recommend
- 00:00:24 checking out before diving into next.js
- 00:00:26 but here's the brief overview vue.js is
- 00:00:29 a front-end javascript framework
- 00:00:31 you use it to build single-page
- 00:00:34 applications or to enhance existing
- 00:00:36 multi-page applications
- 00:00:38 by controlling parts of your page or the
- 00:00:41 entire page
- 00:00:42 through javascript and they're
- 00:00:43 specifically through view chairs which
- 00:00:46 gives you a lot of helper and utility
- 00:00:47 functions
- 00:00:48 that makes the creation of front-end
- 00:00:51 applications running in the browser
- 00:00:52 easier now it's a mixture of angular and
- 00:00:56 react
- 00:00:56 from a syntax perspective you could say
- 00:00:59 it allows you as i said to build widgets
- 00:01:02 and single page applications
- 00:01:04 it includes a router and a state
- 00:01:06 management system
- 00:01:07 view x hence turning it or making it a
- 00:01:10 real
- 00:01:11 complete framework and not just a
- 00:01:13 library for building components as react
- 00:01:16 would be one
- 00:01:17 it's very lightweight that's a huge plus
- 00:01:20 of view chairs
- 00:01:21 and it is extremely popular now you
- 00:01:24 might already know all of that
- 00:01:25 so let's now dive into nux chairs what
- 00:01:28 is that
- 00:01:29 as i said it's a library building up on
- 00:01:31 view chairs and that is super important
- 00:01:33 to understand
- 00:01:35 the question of course just is why do i
- 00:01:37 need
- 00:01:38 a framework for a framework if
- 00:01:41 view js already makes the development of
- 00:01:44 javascript apps easier what's the idea
- 00:01:48 behind next
- 00:01:49 does it make the development of vue.js
- 00:01:51 applications easier
- 00:01:53 the answer would be yes it simplifies
- 00:01:55 the development of
- 00:01:56 vue.js applications and not because
- 00:01:59 vue.js is so difficult it actually isn't
- 00:02:02 but because there are some things which
- 00:02:05 can be made easier
- 00:02:06 for example that's one major focus of
- 00:02:09 next.js
- 00:02:10 the creation of universal apps with
- 00:02:13 universal
- 00:02:14 i simply mean apps that are also
- 00:02:16 rendered on the server
- 00:02:18 now that is important to understand as
- 00:02:20 it's
- 00:02:21 often misunderstood we don't use
- 00:02:24 vue.js and we also don't use next.js
- 00:02:27 on the server as we do use express or
- 00:02:30 hoppy
- 00:02:31 or adonis js or something like that it's
- 00:02:34 not a server-side framework
- 00:02:36 it just allows us to pre-render views on
- 00:02:39 the fly
- 00:02:40 on the server so if you're visiting some
- 00:02:42 page in your vue.js
- 00:02:44 single page application and you enter a
- 00:02:47 url
- 00:02:48 typically what you get is the index.html
- 00:02:50 file and then a single page application
- 00:02:52 where everything is rendered in the
- 00:02:54 browser now you can pre-render things
- 00:02:56 as i said on the fly on the server and
- 00:02:58 next.js makes that easier
- 00:03:00 more on that in a second another thing
- 00:03:03 where
- 00:03:04 next.js helps us and makes things easier
- 00:03:06 is the setup of
- 00:03:08 routes and of the entire project in
- 00:03:10 general
- 00:03:11 in next.js applications you configure a
- 00:03:14 lot
- 00:03:15 simply by creating a folder structure
- 00:03:17 with files in it
- 00:03:18 for example routing as you will see in
- 00:03:21 this video you simply create a bunch of
- 00:03:23 folders and subfolders
- 00:03:24 and these will be converted into your
- 00:03:28 routes
- 00:03:28 of your view application because that's
- 00:03:31 another important
- 00:03:32 thing you still build a viewer
- 00:03:34 application in the end
- 00:03:35 next builds up on view it doesn't
- 00:03:38 replace it
- 00:03:39 so we stick to the view world but gain
- 00:03:42 some extra tools and utilities so in the
- 00:03:45 end
- 00:03:45 it simplifies the development of view
- 00:03:47 apps it's
- 00:03:48 totally optional and since it mostly
- 00:03:51 simplifies things during the development
- 00:03:54 it also doesn't add much to the file
- 00:03:57 size of your project so you don't gain
- 00:04:00 a lot of weight you simply just gain a
- 00:04:02 lot of features
- 00:04:03 during development while still deploying
- 00:04:06 a view app
- 00:04:06 in the end with some overhead with some
- 00:04:09 extra kilobytes to be downloaded
- 00:04:11 but also with some new capabilities like
- 00:04:14 the server-side rendering
- 00:04:16 now let's dive into all of that and
- 00:04:18 let's take a closer look at
- 00:04:19 how this works in reality and not just
- 00:04:22 on the slide
- 00:04:23 however there is one more thing i want
- 00:04:25 to show you on a slide and that's the
- 00:04:26 server-side rendering part
- 00:04:27 because it's so crucial to get that
- 00:04:29 right
- 00:04:31 i already said we're building a single
- 00:04:33 page application with
- 00:04:34 viewjs so we're building an application
- 00:04:37 that runs
- 00:04:38 in the browser that's super important to
- 00:04:40 understand it's a client-side framework
- 00:04:43 how does server-side rendering fit in
- 00:04:45 there
- 00:04:46 let's consider this case we have our
- 00:04:48 user you
- 00:04:49 and you're visiting a website which is
- 00:04:52 built with
- 00:04:52 vue.js so you send a request to a server
- 00:04:55 by entering a url for example
- 00:04:58 now typically you would get back a
- 00:05:00 response and if you have a single page
- 00:05:02 application
- 00:05:03 that response is the index.html file
- 00:05:06 which contains your view app
- 00:05:07 it contains a bunch of scripts importing
- 00:05:09 the view app you could say
- 00:05:11 from that point on everything runs in
- 00:05:13 the browser and if you click around in
- 00:05:15 that application
- 00:05:16 you never send a new request you never
- 00:05:19 send
- 00:05:19 or get back a new response or if you do
- 00:05:23 these will be behind the scenes ajax
- 00:05:25 requests and responses
- 00:05:26 so you always stay on that index.html
- 00:05:29 file and the view app the
- 00:05:31 viewchairs framework simply re-renders
- 00:05:33 the parts of your page
- 00:05:35 that needs to be re-rendered to reflect
- 00:05:38 the new
- 00:05:39 url you are now on even though it's
- 00:05:41 technically the same page
- 00:05:44 now the problem with single page
- 00:05:45 applications is
- 00:05:47 that if you have a page let's say a blog
- 00:05:50 where you get a lot of posts that are
- 00:05:52 fetched from a database
- 00:05:54 what would happen is that you got the
- 00:05:55 index.html file with the view app
- 00:05:58 and once it starts in the browser once
- 00:05:59 it runs in your browser
- 00:06:01 it starts fetching the blog posts behind
- 00:06:04 the scenes with the ajax request
- 00:06:06 and it will render them to the screen
- 00:06:07 once they're there from a ui
- 00:06:09 or from a user experience perspective
- 00:06:11 that is fine
- 00:06:13 from a search engine perspective this is
- 00:06:15 problematic
- 00:06:16 because the search engine crawler won't
- 00:06:19 wait for the data to return
- 00:06:21 so all the crawler will see is an empty
- 00:06:23 page
- 00:06:24 or just the spinner or whatever you're
- 00:06:26 showing there
- 00:06:27 now this is where server-side rendering
- 00:06:29 can help you you're not creating a
- 00:06:31 server-side app you're not having a
- 00:06:32 replacement for express or something
- 00:06:34 like that here
- 00:06:35 instead the index.html file which
- 00:06:38 contains your view app
- 00:06:39 can be pre-rendered on the server for
- 00:06:42 each new request
- 00:06:43 so not when you click around on the app
- 00:06:45 so when the user is using your page
- 00:06:47 but whenever a new url is entered and
- 00:06:50 you hit
- 00:06:50 enter or you hit refresh in your browser
- 00:06:53 and the search engine crawler
- 00:06:54 effectively does
- 00:06:55 just that it visits different urls and
- 00:06:58 each url
- 00:06:59 is a brand new fetch of your page for
- 00:07:02 these requests
- 00:07:03 we can pre-render the index.html file to
- 00:07:06 execute that
- 00:07:07 initial view code that should run not in
- 00:07:10 your browser
- 00:07:11 but on the server that is the key thing
- 00:07:14 we pre-render it on the fly upon the
- 00:07:17 request
- 00:07:18 for the first load only that's important
- 00:07:21 for the first load only
- 00:07:23 thereafter we again have a single page
- 00:07:25 application running in the browser we
- 00:07:27 still have a normal view application
- 00:07:29 so if you then click around in this
- 00:07:30 pre-rendered page
- 00:07:32 you still send your ajax requests and
- 00:07:34 you have view manage everything
- 00:07:36 but that first request is pre-rendered
- 00:07:38 on the server
- 00:07:39 you can do that without nexjs you can
- 00:07:42 find a link to the official server-side
- 00:07:43 rendering guide
- 00:07:44 of the vue chairs framework in the
- 00:07:46 description below
- 00:07:48 but setting it up manually is a lot of
- 00:07:50 work and not that much fun
- 00:07:52 next js helps you with that that's
- 00:07:54 exactly what naxxjs does
- 00:07:56 it helps you with that pre-rendering of
- 00:07:58 that first initial page
- 00:08:01 and besides that whole server-side
- 00:08:03 rendering stuff it also makes the
- 00:08:05 creation of
- 00:08:06 your app simpler because it uses that
- 00:08:08 configure
- 00:08:09 a lot by creating folders and files
- 00:08:11 approach which we'll have a look at
- 00:08:13 so this is what nextjs does this is what
- 00:08:15 the server-side rendering does mean here
- 00:08:17 now let's take a look and let's simply
- 00:08:19 create a next step to get a better
- 00:08:21 feeling for what happens
- 00:08:22 and to leave that world of theory here
- 00:08:25 to create a new next app i will use
- 00:08:28 create next app
- 00:08:29 which is like a cli you could say it is
- 00:08:32 a tool
- 00:08:32 which you execute from the command line
- 00:08:34 from the terminal on mac
- 00:08:36 which makes the creation of next app
- 00:08:39 simpler
- 00:08:40 and it's available for or it will work
- 00:08:42 for both mac linux and also for windows
- 00:08:45 of course
- 00:08:45 so it works there in all these
- 00:08:47 environments you can simply google for
- 00:08:50 create next app and you should find this
- 00:08:52 github repository here
- 00:08:54 from the next community and on that
- 00:08:56 github page
- 00:08:57 you can find detailed instructions and
- 00:08:59 also installation instructions
- 00:09:01 now we will actually use a third way of
- 00:09:03 installing it which you don't see on
- 00:09:05 that page
- 00:09:06 and we will use node.js which you need
- 00:09:08 under all circumstances
- 00:09:10 because the project created with this
- 00:09:12 cli tool here
- 00:09:14 will have a development server so that
- 00:09:16 you can preview your application
- 00:09:18 and that development server will use
- 00:09:20 node.js as a
- 00:09:22 language so we need node.js
- 00:09:25 and you can get it from nodejs.org
- 00:09:28 there you can simply download the latest
- 00:09:30 version or the long term stability
- 00:09:33 version if you're facing issues with the
- 00:09:34 latest one
- 00:09:35 though if you don't then i would
- 00:09:37 recommend using the latest one
- 00:09:39 and we will use it for the development
- 00:09:40 server and because we're interested in
- 00:09:43 nodes package manager npm which i will
- 00:09:46 use
- 00:09:46 to install create next app once you ran
- 00:09:49 through
- 00:09:50 the node installer and got npm also
- 00:09:52 installed you can execute npm install
- 00:09:54 dash
- 00:09:55 g create next
- 00:09:59 app that's the name of the package this
- 00:10:01 tool i was just talking about and
- 00:10:04 on mac and linux you probably need to
- 00:10:05 add a sudo in front of that to get the
- 00:10:07 right permissions
- 00:10:09 and once that is running it will
- 00:10:10 download that tool and install it
- 00:10:12 globally on your machine so you only
- 00:10:14 need to execute this command once
- 00:10:16 and no second time thereafter unless you
- 00:10:19 want to update it
- 00:10:20 you can now use it anywhere on your
- 00:10:22 machine so now it was installed
- 00:10:24 you can now navigate in the terminal or
- 00:10:26 command prompt
- 00:10:27 into the folder where you want to create
- 00:10:28 your next project and i
- 00:10:30 already am in this folder so i will now
- 00:10:33 just run create
- 00:10:34 dash nux dash app so the name of that
- 00:10:36 package we just installed
- 00:10:39 my first next app or whatever name you
- 00:10:43 want to use
- 00:10:44 maybe since i want to use a very simple
- 00:10:46 recipe
- 00:10:47 application i will name it recipes but
- 00:10:50 the name is up to you
- 00:10:51 you hit enter and now you're asked a
- 00:10:53 couple of questions like a project name
- 00:10:55 i'll confirm the default which you see
- 00:10:57 here between the parentheses with
- 00:10:59 enter description my
- 00:11:04 awesome recipe book app
- 00:11:08 you can now choose a custom server-side
- 00:11:10 framework and that can be confusing
- 00:11:12 now i said that next would not be a
- 00:11:15 replacement for express and so on
- 00:11:17 and it isn't but you can integrate it
- 00:11:19 with express
- 00:11:20 or also with no server-side framework in
- 00:11:23 this case
- 00:11:23 next will alter for production not not
- 00:11:26 just for development
- 00:11:27 give you a node server which you deploy
- 00:11:30 because it of course
- 00:11:31 needs a node server to be able to
- 00:11:33 pre-render
- 00:11:34 your pages on the fly and it only runs
- 00:11:37 on node that's always important
- 00:11:39 you can't use it with php or anything
- 00:11:41 like that so i will use
- 00:11:43 non here i don't want to have another
- 00:11:45 server-side framework because i don't
- 00:11:47 want to write any server-side code here
- 00:11:49 i just want to get that pre-rendering
- 00:11:51 capability
- 00:11:52 so i will pick none here now we could
- 00:11:55 also choose a custom ui
- 00:11:56 framework and these are really component
- 00:11:59 libraries
- 00:12:00 where we could easily integrate things
- 00:12:02 like a date picker and so on into our
- 00:12:04 project
- 00:12:05 i don't want one of these either so i
- 00:12:07 will also pick none here
- 00:12:10 and now we can choose the default
- 00:12:11 rendering mode which you can change
- 00:12:13 after the project has been created
- 00:12:16 you could still create a single page
- 00:12:17 application hence you would not use the
- 00:12:20 server side rendering capabilities
- 00:12:22 you would still benefit from that
- 00:12:25 configure everything with
- 00:12:27 files and folders approach but i also
- 00:12:30 want to get that server-side rendering
- 00:12:32 advantage or feature so i will pick
- 00:12:35 universal here which simply means the
- 00:12:37 app then supports both the client and
- 00:12:39 the server side
- 00:12:40 though technically it still is a
- 00:12:42 client-side focused app
- 00:12:44 you just got that server-side
- 00:12:45 pre-rendering capability
- 00:12:47 so i will pick universal here now next
- 00:12:49 you could
- 00:12:50 automatically include axias into your
- 00:12:53 project
- 00:12:54 axias is a javascript library which you
- 00:12:56 can use to send ajax requests
- 00:12:58 but we can also install that separately
- 00:13:00 if we wanted to so i will hit
- 00:13:01 no here you can enable linting here i
- 00:13:04 will also hit no here and you can enter
- 00:13:06 your offer name here just to store it in
- 00:13:10 the configuration
- 00:13:11 next you can choose the packager manager
- 00:13:13 you want to install if you got multiple
- 00:13:15 ones installed
- 00:13:16 now i also got yarn installed but i will
- 00:13:18 stick to npm
- 00:13:19 and that will now create a new next
- 00:13:22 project with the
- 00:13:23 bare minimum settings which are
- 00:13:26 basically what you will start with in a
- 00:13:28 lot of projects
- 00:13:29 so let's wait for this to finish and i
- 00:13:31 will back once it is done
- 00:13:33 so the setup finished and now we see the
- 00:13:35 commands we can execute here
- 00:13:36 so let me navigate into that newly
- 00:13:38 created folder with cd recipes
- 00:13:41 and now here we can run npm run dev to
- 00:13:44 start that development server
- 00:13:46 now this will start at localhost 3000 by
- 00:13:49 default
- 00:13:50 it also prints the address here
- 00:13:53 and you can now simply visit that
- 00:13:54 address so i entered it in the browser
- 00:13:57 and you should see something like that
- 00:13:59 a default next app basically a starting
- 00:14:02 screen it gives you out of the box
- 00:14:04 now let me also quickly open this in an
- 00:14:06 ide
- 00:14:07 i will use visual studio code here in
- 00:14:09 this video
- 00:14:11 and there it should look something like
- 00:14:13 this this is the folder and file
- 00:14:15 structure a next project has
- 00:14:17 out of the box and if you have worked
- 00:14:19 with vue.js
- 00:14:20 only thus far then this will look quite
- 00:14:23 differently
- 00:14:24 the reason for this is you still create
- 00:14:26 a view js application
- 00:14:28 but a lot of things you had to configure
- 00:14:30 and wire up manually
- 00:14:32 in your view apps mainly related to the
- 00:14:35 routing
- 00:14:35 is now done for you the core
- 00:14:39 concept of a next app which i absolutely
- 00:14:42 want you to remember
- 00:14:43 is that pages folder here
- 00:14:46 in that pages folder you create your
- 00:14:49 routes
- 00:14:50 by naming your files and folders in
- 00:14:52 there appropriately
- 00:14:54 every dot view file in that pages folder
- 00:14:58 will be considered as a route
- 00:15:00 and you can also nest routes and create
- 00:15:02 more complex paths
- 00:15:04 by creating subfolders let me show you
- 00:15:07 what i mean
- 00:15:07 if i add an about dot view file
- 00:15:11 and these should be dot view files for
- 00:15:13 normal single file view components as
- 00:15:15 you probably
- 00:15:16 know them from your own view project if
- 00:15:18 you create such a about the view file
- 00:15:21 file you can simply add a template in
- 00:15:23 there and in the template
- 00:15:24 you could output an h1 tag where you say
- 00:15:28 the about page
- 00:15:33 something like that now if i save this
- 00:15:35 about dot view file
- 00:15:37 and i go back to my project here then
- 00:15:40 i can go to my url and enter slash about
- 00:15:44 now this will load this page i just
- 00:15:46 created you
- 00:15:47 might need to reload once if you just
- 00:15:49 added that page
- 00:15:50 and it will print out the about page
- 00:15:53 here so it loads
- 00:15:55 this content this view component here
- 00:15:59 in the about.view file as my
- 00:16:02 main component through the view router
- 00:16:04 behind the scenes
- 00:16:06 because i added an about.view file here
- 00:16:09 each file is interpreted as a route here
- 00:16:13 index simply is the root route for just
- 00:16:15 slash nothing
- 00:16:16 and slash about would be forwarded to
- 00:16:18 about.view
- 00:16:20 an alternative by the way if i cut that
- 00:16:22 content here and remove the file
- 00:16:24 an alternative is to create a subfolder
- 00:16:26 about
- 00:16:27 and in that subfolder i could create an
- 00:16:29 index.viewfile again
- 00:16:31 if i now save this and i reload the
- 00:16:33 previous page
- 00:16:35 then it will still work because this
- 00:16:37 yields the same result in the end
- 00:16:40 a folder is also interpreted as a path
- 00:16:42 segment
- 00:16:43 and the index file in a folder will
- 00:16:46 simply be loaded if you enter nothing
- 00:16:48 else and if you get no other dot view
- 00:16:50 files in that folder
- 00:16:51 and i personally prefer this folder
- 00:16:54 based approach because i believe or i
- 00:16:56 think
- 00:16:56 it makes the structure a bit more
- 00:16:58 understandable this way
- 00:17:00 so this is how you create routes and
- 00:17:02 that is the second core
- 00:17:04 feature of next.js we also get a couple
- 00:17:06 of other
- 00:17:07 folders here which you use for different
- 00:17:09 features we will have a look at
- 00:17:11 some of them in this video but the pages
- 00:17:13 folder is the most crucial one
- 00:17:15 you create your routes through the view
- 00:17:17 router without writing
- 00:17:19 any single line of configuration code
- 00:17:22 just by creating folders and files
- 00:17:24 and now if you inspect the source code
- 00:17:27 of that loaded page by right clicking
- 00:17:29 and then viewing the page source
- 00:17:34 then you will see that if you scroll
- 00:17:36 down
- 00:17:37 that this is actually pre-rendered
- 00:17:40 you can see it here
- 00:17:44 the about page now this might look
- 00:17:47 trivial because that is what you entered
- 00:17:49 here right
- 00:17:50 but if you create a normal view app
- 00:17:52 without
- 00:17:53 next and you dare inspect your page
- 00:17:56 source
- 00:17:57 you will basically see an empty
- 00:17:59 index.html file
- 00:18:00 with a bunch of script imports you see
- 00:18:03 these
- 00:18:04 script imports here too because after
- 00:18:06 the first load it becomes a single page
- 00:18:08 application
- 00:18:09 but this first page is pre-rendered on
- 00:18:12 the fly
- 00:18:12 just before you or just write after you
- 00:18:15 request it
- 00:18:16 on the server as is confirmed by the
- 00:18:18 fact that the content is in the file
- 00:18:20 which you download from the server
- 00:18:22 if it would be added after the initial
- 00:18:25 load
- 00:18:25 then this source code wouldn't have been
- 00:18:28 touched because
- 00:18:29 javascript changes are reflected in
- 00:18:31 there this is really the file you got
- 00:18:32 from the server
- 00:18:34 so these are the two main features of
- 00:18:37 next
- 00:18:37 the server side rendering and the
- 00:18:39 navigation or the routing
- 00:18:41 by folders and files now
- 00:18:44 let's build up on that and let's create
- 00:18:46 a very very
- 00:18:48 very simple page here where we have some
- 00:18:51 recipes to look at
- 00:18:52 and if you want to learn more about nux
- 00:18:54 and dive a bit deeper i got a whole
- 00:18:56 course on that where i walk you through
- 00:18:57 the different core features and give you
- 00:18:59 a more
- 00:18:59 photo introduction to next.js a link is
- 00:19:02 of course in the video description
- 00:19:04 so let's create a new subfolder in the
- 00:19:06 pages folder and let's name it
- 00:19:08 recipes and in there i'll add an
- 00:19:10 index.viewfile
- 00:19:11 now my goal is to show very very simple
- 00:19:15 previews of recipes we could cook in in
- 00:19:18 there
- 00:19:18 and if we click one we load a detail
- 00:19:20 page which will also be very simple in
- 00:19:22 this video
- 00:19:23 but which will allow us to see naxjs in
- 00:19:26 action
- 00:19:27 so in the index.view file in the recipes
- 00:19:29 folder i'll add a template
- 00:19:31 and in that template here i well when i
- 00:19:33 display my index
- 00:19:35 my recipes so i'll add a section maybe
- 00:19:38 give that section a class of
- 00:19:39 recipes and in there i want to have a
- 00:19:41 couple of a couple of
- 00:19:42 article elements so these are normal
- 00:19:46 html elements of course and each article
- 00:19:49 let's say
- 00:19:50 could have um like a div where we have a
- 00:19:53 preview image
- 00:19:55 could have ih1 tag for the title
- 00:19:58 and could then maybe have a paragraph
- 00:20:01 where we have some nice
- 00:20:04 preview text
- 00:20:07 now since we're creating a normal view
- 00:20:09 application a new view component here
- 00:20:11 in the index.u file we can of course
- 00:20:13 also add some styles
- 00:20:15 and we can add the scoped keyword to
- 00:20:18 scope the styling we set up here to just
- 00:20:20 this component and therefore to this
- 00:20:22 page
- 00:20:23 so in there i now want to add my recipes
- 00:20:26 class which i'm
- 00:20:27 referencing in the template and in there
- 00:20:30 i will have my article which is just a
- 00:20:33 recipe
- 00:20:34 and actually i also want to style that
- 00:20:38 and let's say a recipe has a very simple
- 00:20:40 style
- 00:20:41 box sizing of border box to make sure
- 00:20:45 the width and so on is correct
- 00:20:46 give it a width of let's say 280
- 00:20:50 pixels maybe give it a padding of
- 00:20:54 8 pixels give it a border of
- 00:20:58 1 pixel solid and a light gray maybe
- 00:21:01 and some box shadow of zero
- 00:21:04 then two pixels uh as a second value
- 00:21:07 then maybe two
- 00:21:08 pixels again and a darker gray
- 00:21:12 excuse me darker gray like this and the
- 00:21:15 exact styling is of course totally up to
- 00:21:16 you
- 00:21:17 now if we take a very quick look at
- 00:21:21 slash recipes like this
- 00:21:25 and for the first time you need to
- 00:21:26 reload this page this is what it will
- 00:21:28 look like
- 00:21:29 now i want to have an image above it and
- 00:21:31 of course i want to have multiple
- 00:21:32 recipes
- 00:21:33 so let's quickly copy that recipe here
- 00:21:37 add it below the first one and save that
- 00:21:41 file you get live updating here always
- 00:21:43 make sure you keep that process running
- 00:21:45 by the way which you started with npm
- 00:21:47 run dev
- 00:21:48 so now we got a second recipe and i want
- 00:21:50 to position them next to each other
- 00:21:52 so i'll give the wrapping recipes
- 00:21:55 container here
- 00:21:56 a display of flex to use flexbox and
- 00:21:59 set the flex flow to
- 00:22:02 row and give it also the wrap
- 00:22:06 property to make sure we wrap the
- 00:22:08 content if
- 00:22:09 our page uh with dozens of files so if
- 00:22:12 we are in a smaller page
- 00:22:14 this will automatically wrap to have
- 00:22:16 very basic responsive styling here
- 00:22:18 okay so these are the two basic recipes
- 00:22:21 now i want to have an image
- 00:22:22 so let's quickly search for food and
- 00:22:24 feel free to pick
- 00:22:26 any image that looks delicious to you so
- 00:22:28 we'll grab the url of this image which
- 00:22:30 looks quite tasty
- 00:22:32 and i want to use it as a background
- 00:22:34 image for that div in my
- 00:22:36 recipe here so why don't we give
- 00:22:39 that div you're in both instances a
- 00:22:42 class
- 00:22:42 of thumbnail
- 00:22:46 and then also inline style which we can
- 00:22:50 later set dynamically if we want to
- 00:22:53 which sets a background image where we
- 00:22:55 set some url
- 00:22:57 like this and simply reference the url
- 00:23:01 now we can style the thumbnail class
- 00:23:03 here to position that
- 00:23:05 background image correctly
- 00:23:08 by setting background
- 00:23:15 position to center and background
- 00:23:19 size maybe to cover now if we save this
- 00:23:22 and we go back to our application
- 00:23:25 we still don't see anything because what
- 00:23:27 we also need to do is
- 00:23:28 set a width of 100 and a height
- 00:23:31 of let's say 200 pixels if we do that
- 00:23:35 and we go back we see our image there
- 00:23:38 now this is now my preview image of that
- 00:23:41 recipe the recipe itself could also use
- 00:23:44 some
- 00:23:45 margin to have some distance to the next
- 00:23:46 recipe in my opinion so let's add a
- 00:23:48 margin of 10 pixels to all directions
- 00:23:50 looks better and of course i want to
- 00:23:52 have a different image for
- 00:23:54 the second recipe so let's search one
- 00:23:57 other image
- 00:23:58 maybe some no not this one this one
- 00:24:01 looks quite good
- 00:24:05 so with this one selected let's go back
- 00:24:07 and add it to this url and as i said we
- 00:24:10 can of course set this dynamically by
- 00:24:12 binding the style property just as you
- 00:24:14 can do it in any
- 00:24:15 view app and with that we got this
- 00:24:19 exchanged so this is taking shape
- 00:24:22 now one thing i want to do in the
- 00:24:23 recipes here i want to change the
- 00:24:25 positioning
- 00:24:26 so i'll set justify content which is a
- 00:24:28 flexbox property
- 00:24:29 choose center and align
- 00:24:32 items also to center to center them
- 00:24:36 horizontally and vertically in their
- 00:24:39 flexbox not on the entire page so this
- 00:24:41 gives me this look
- 00:24:42 so this looks quite nice now one thing
- 00:24:44 we can of course do in next apps too
- 00:24:46 and that is something i definitely want
- 00:24:48 to show you we can of course
- 00:24:50 still create normal view components
- 00:24:52 which are not used as pages
- 00:24:55 to construct our app from them for that
- 00:24:57 we got this components folder
- 00:24:59 and we already start with a logo
- 00:25:01 component now let's get rid of that
- 00:25:03 and let's create a new dot view file in
- 00:25:05 there so just an ordinary view component
- 00:25:07 as we used it in the pages folder
- 00:25:09 components in the components folder
- 00:25:11 however
- 00:25:12 will not be treated as routes but as
- 00:25:14 normal components which you can use
- 00:25:16 anywhere else in your
- 00:25:18 next application once you registered
- 00:25:20 them so here
- 00:25:21 i will create my recipe.viewfile
- 00:25:26 and let's follow the styling convention
- 00:25:28 and name this
- 00:25:30 recipe like that and in there i got a
- 00:25:33 template too of course
- 00:25:35 and in this template i now want to use
- 00:25:37 this
- 00:25:38 markup which i used in my index view
- 00:25:40 file in the recipes folder
- 00:25:42 so the code for one single recipe
- 00:25:45 essentially
- 00:25:46 this is now what i enter in this
- 00:25:48 template here
- 00:25:50 now the image the title and their
- 00:25:52 preview text that is something which i
- 00:25:54 expect to get from outside
- 00:25:56 from the page so what i'll do
- 00:26:01 is i will add a script section which we
- 00:26:03 could have also added to the components
- 00:26:05 in the pages folder of course
- 00:26:06 you're just creating a normal view
- 00:26:08 component
- 00:26:10 now in this script section here i'll add
- 00:26:13 a props key here to define the props
- 00:26:16 this
- 00:26:17 component expects and i will use the
- 00:26:20 very short version here i expect to get
- 00:26:24 a thumbnail i expect to get a title
- 00:26:27 and a preview text now
- 00:26:30 with that set up we can output this with
- 00:26:32 the normal tools
- 00:26:34 view gives us because that's really
- 00:26:36 important to understand you're creating
- 00:26:37 a view app so you use the same syntax
- 00:26:39 here
- 00:26:40 you just got some extra helpers in the
- 00:26:42 form of next
- 00:26:43 features so here i'll output the preview
- 00:26:47 text
- 00:26:49 and for the title here i'll output the
- 00:26:52 title property referring to this
- 00:26:54 prop and for the image here i'll bind
- 00:26:58 style here to a dynamic value to a
- 00:27:00 javascript
- 00:27:01 object where i got background image
- 00:27:05 using camel case since we're now
- 00:27:07 entering some javascript snippet in here
- 00:27:10 and close the object at the end and here
- 00:27:13 the url
- 00:27:14 is now something which i get dynamically
- 00:27:18 first of all this has to be a string now
- 00:27:20 because it is a javascript
- 00:27:23 value assigned to this property in this
- 00:27:25 object
- 00:27:26 so url like this and then i escape here
- 00:27:30 and close it and then here i want to
- 00:27:32 enter my thumbnail
- 00:27:34 and closing and close it in this url
- 00:27:38 and we need to close that string after
- 00:27:39 the closing parenthesis
- 00:27:41 so now we're assigning a dynamic value
- 00:27:43 to this background image which we in
- 00:27:45 turn
- 00:27:46 bind in this object to the style
- 00:27:48 property and now we get a reusable
- 00:27:50 component
- 00:27:51 which we can use by registering it in
- 00:27:53 our recipes
- 00:27:54 page in there to register it i'll also
- 00:27:57 add a script section
- 00:28:00 like this and now i can simply import it
- 00:28:04 by writing import recipe
- 00:28:07 from and now in next projects one of the
- 00:28:09 utilities it gives you
- 00:28:11 you can use add to refer to the root
- 00:28:13 folder
- 00:28:14 and therefore next slash components
- 00:28:17 slash
- 00:28:17 recipe and omit the dot view
- 00:28:20 this gives you direct access to this
- 00:28:22 recipe component
- 00:28:24 which you can now rest a register on the
- 00:28:26 components key in your view
- 00:28:28 object here in your view component
- 00:28:30 instance object
- 00:28:31 so here under components i can register
- 00:28:34 recipe like that this allows us to use
- 00:28:38 recipe in the template here so i replace
- 00:28:42 the article
- 00:28:43 with just recipe a self-closing element
- 00:28:46 if you want so
- 00:28:47 and there we can pass the thumbnail now
- 00:28:50 for that it would
- 00:28:51 have been nice to keep the image linked
- 00:28:53 so let's quickly do that
- 00:28:55 scrap that link again and now
- 00:28:58 do the changes and now reference
- 00:29:02 thumbnail and set that link
- 00:29:05 and let's split this over multiple lines
- 00:29:07 to keep it readable
- 00:29:08 we can also set a title here like
- 00:29:11 delicious
- 00:29:15 pizza and a preview text
- 00:29:19 which could be awesome
- 00:29:23 pizza yeah it's really descriptive as
- 00:29:25 you can see
- 00:29:26 now we can repeat that for second recipe
- 00:29:30 here
- 00:29:31 let's grab that url that image url
- 00:29:35 and use that here and now this is not a
- 00:29:38 visa
- 00:29:38 this is some sea food
- 00:29:41 salad or something like that or is it i
- 00:29:44 don't know
- 00:29:45 it's something like that so seafood cell
- 00:29:47 seafood salad
- 00:29:49 very tasty indeed
- 00:29:53 and let's remove that article so now
- 00:29:55 we're mixing next with something which
- 00:29:57 we already know
- 00:29:59 reusable components we know how to use
- 00:30:01 them in
- 00:30:02 a view app don't we make sure to save
- 00:30:05 all files and if you now return
- 00:30:08 got an error regarding the logo which is
- 00:30:10 still important in the main index file
- 00:30:12 let's remove it there can actually clear
- 00:30:16 can actually clear the entire stuff down
- 00:30:18 there the style the script
- 00:30:20 and remove the content here in the
- 00:30:22 section
- 00:30:24 so if you save that updated file
- 00:30:27 we get that now the image is missing
- 00:30:29 what's broken here let's quickly have a
- 00:30:30 look
- 00:30:31 we got our thumbnail and we're binding
- 00:30:34 background image to a url here
- 00:30:37 and the problem i have of course is the
- 00:30:40 styling
- 00:30:41 we get the styles for the recipe in the
- 00:30:44 recipes index.viewfile
- 00:30:46 let's cut them from there the recipe in
- 00:30:48 the thumbnail and go to the recipe
- 00:30:50 recipe.viewfile and add them there of
- 00:30:53 course
- 00:30:53 also scope them
- 00:30:58 and now enter the styles in there save
- 00:31:01 that file
- 00:31:02 and now we're back to where we already
- 00:31:04 were so now we're
- 00:31:06 having the two recipes here on that page
- 00:31:09 and we're outputting them there
- 00:31:11 now what if we wanted to click on one of
- 00:31:14 them
- 00:31:14 and then see the details page for that
- 00:31:17 we might want to go to something like
- 00:31:18 slash recipes
- 00:31:20 slash one for the id one
- 00:31:23 now you can also have dynamic paths in
- 00:31:25 noxjs by adding a subfolder
- 00:31:27 underscore that is important part the
- 00:31:30 underscore in the name of the folder or
- 00:31:32 the file
- 00:31:33 signals to next that the part after it
- 00:31:37 will be some variable some dynamic
- 00:31:40 parameter by which you can extract what
- 00:31:42 the user entered
- 00:31:43 so something like maybe id underscore id
- 00:31:47 and there i again create the
- 00:31:49 index.viewfile
- 00:31:50 and in that file for now i'll simply
- 00:31:52 output a paragraph where i just want to
- 00:31:54 output the id the user entered
- 00:31:57 and since it uses the normal view router
- 00:31:59 behind the scenes
- 00:32:00 you can reference dollar sign route that
- 00:32:03 is an
- 00:32:04 object automatically made available by
- 00:32:06 view
- 00:32:07 also in normal view apps where you use
- 00:32:09 the router by the way
- 00:32:11 and there you will have a params object
- 00:32:14 and now i can enter or access id on that
- 00:32:17 params object
- 00:32:18 because that folder is named id
- 00:32:21 the underscore is ignored it just
- 00:32:23 signals to next
- 00:32:25 that this is a dynamic segment and then
- 00:32:28 you enter the name in this case
- 00:32:29 id by which you plan on extracting that
- 00:32:32 parameter
- 00:32:33 and route parents is just a default
- 00:32:35 object given to you
- 00:32:36 by the vue.js router which next uses as
- 00:32:40 i said
- 00:32:41 with that if we save that file and we go
- 00:32:44 manually for now to recipes one then i
- 00:32:47 output one here
- 00:32:49 maybe it will charge to c but there is a
- 00:32:50 one that is that dynamic
- 00:32:53 segment i was referring to now this
- 00:32:56 gives us the opportunity of loading this
- 00:32:58 dynamically
- 00:32:59 so in here we could have a section class
- 00:33:03 single recipe and in there let's say we
- 00:33:07 have a h1 tag
- 00:33:08 where i want to output the title
- 00:33:14 then i let's say want to output a div
- 00:33:17 where i have my my image
- 00:33:21 and below that i have a paragraph with
- 00:33:24 the
- 00:33:25 recipe description and you can of course
- 00:33:27 always
- 00:33:28 enter more details now with that we got
- 00:33:32 a very basic page here without any
- 00:33:34 styling so let's quickly add some
- 00:33:35 styling with normal css
- 00:33:38 single recipe here i'll again use
- 00:33:41 flexbox to give it some styling so
- 00:33:44 display is set to flex
- 00:33:46 and then i'll set the justify content
- 00:33:49 property
- 00:33:49 to center to center everything again and
- 00:33:52 so
- 00:33:53 i do for align items to center this too
- 00:33:57 now with that we get some very basic
- 00:33:59 styling which we can always find here
- 00:34:01 later i also want to align all the text
- 00:34:03 in the center so let's
- 00:34:05 quickly enter text align center too and
- 00:34:08 let's
- 00:34:08 maybe give this
- 00:34:13 padding of 30 pixels if we want to
- 00:34:16 and now let's make sure we can reach
- 00:34:18 that page without
- 00:34:20 having to enter it manually so here on
- 00:34:22 the index.view file in the recipes
- 00:34:24 folder where we got our recipes
- 00:34:26 i want to get forwarded to that detail
- 00:34:29 page if we click one of the recipes
- 00:34:31 now for that let's simply assume that
- 00:34:33 each recipe here
- 00:34:35 also receives an id maybe one for the
- 00:34:37 first one and two for the second one
- 00:34:40 and in reality we would of course get
- 00:34:42 that recipe data from a database where
- 00:34:44 we probably also have ids for all the
- 00:34:46 recipes
- 00:34:47 here it's hard coded but that's just a
- 00:34:49 simple example here
- 00:34:50 so we got id 1 and id 2 here and
- 00:34:53 with that i want to output it of course
- 00:34:56 i want to
- 00:34:57 output the id or to be precise i want to
- 00:34:59 output a link which uses that id
- 00:35:02 so back in the recipe.view file here
- 00:35:06 first of all i'll add a new prop which i
- 00:35:08 expect
- 00:35:09 so i'll expect the id prop which we just
- 00:35:11 added
- 00:35:12 and now i will wrap this entire article
- 00:35:14 in a link however
- 00:35:16 not in a normal link not in an anchor
- 00:35:18 tag which i write manually
- 00:35:20 but in a next link object or component
- 00:35:23 now that is as the name suggests made
- 00:35:26 available by next
- 00:35:28 and it uses the view router router link
- 00:35:30 behind the scenes
- 00:35:32 in the end what this does or how this
- 00:35:34 works is you enter a tube property
- 00:35:37 with a path you want to navigate to now
- 00:35:40 here i will bind this dynamically by
- 00:35:42 adding a colon
- 00:35:43 and then i want to go to slash recipes
- 00:35:46 this should be a string because we're
- 00:35:47 binding to a javascript expression with
- 00:35:49 the colon here
- 00:35:51 slash recipes slash and then i will add
- 00:35:55 the id
- 00:35:56 now with that if we save this it looks
- 00:35:59 ugly because of the styling but
- 00:36:00 you can already see it's a link and if i
- 00:36:02 click on the first one
- 00:36:04 i'm taken to the detail page and the
- 00:36:06 same will be the case
- 00:36:08 for the second one so this works fine
- 00:36:11 one thing i do notice is the styling is
- 00:36:13 a bit off we
- 00:36:15 should set flex flow in that single
- 00:36:18 recipe page
- 00:36:20 to column to not put it next to each
- 00:36:23 other but below each other
- 00:36:25 so now we got the recipe detail pages
- 00:36:28 and you can see that we can go there
- 00:36:30 with a dynamic path parameter
- 00:36:32 by using that underscore in the folder
- 00:36:34 name
- 00:36:36 so with all that set up we got a way of
- 00:36:38 navigating around here in our
- 00:36:40 simple application now of course we can
- 00:36:44 enhance the styling in the recipe.view
- 00:36:46 file in the components folder
- 00:36:48 there i simply want to change my link
- 00:36:52 and behind the scenes it will use a
- 00:36:53 normal anchor tag so we can style that
- 00:36:56 so in that normal anchor tag i want to
- 00:36:58 disable
- 00:37:00 text decoration so set this to none
- 00:37:03 and i'll set the color to black
- 00:37:06 still to not have that blue text
- 00:37:09 now it's still clickable but it looks a
- 00:37:11 bit nicer
- 00:37:13 so now we can go to the detail pages now
- 00:37:16 to output something on the detail pages
- 00:37:18 we simply need to
- 00:37:19 load our data now we could use view x
- 00:37:22 you can use
- 00:37:23 view x and next applications too and a
- 00:37:26 link to instructions on how to use it
- 00:37:29 can be found in the video description or
- 00:37:31 of course also in that course i
- 00:37:33 mentioned earlier
- 00:37:34 in this video i want to load the data
- 00:37:37 from the server
- 00:37:38 it just adds the initial list of recipes
- 00:37:41 now we don't do that yet
- 00:37:42 so for now let's hard code it but i'll
- 00:37:44 soon add a way of loading this
- 00:37:46 dynamically
- 00:37:47 so for now i simply want to output the
- 00:37:49 id here so that we can really see a
- 00:37:51 difference
- 00:37:52 by accessing dollar sign route again
- 00:37:54 this is provided by the normal view
- 00:37:56 router
- 00:37:57 params which is a default object or
- 00:38:00 property of that
- 00:38:02 dollar sign route object and now id
- 00:38:05 because the folder is named underscore
- 00:38:07 id
- 00:38:08 now with that we can at least see a
- 00:38:10 difference if we click on that we see
- 00:38:11 two for that recipe
- 00:38:13 and one for the other one now
- 00:38:17 as i said a second ago in reality you
- 00:38:20 would not hard code this you would load
- 00:38:22 it from a server
- 00:38:23 right and this is what i also want to do
- 00:38:26 here
- 00:38:26 or at least what i want to fake we can
- 00:38:29 add a special method and let's start
- 00:38:31 with the recipes page
- 00:38:33 there in our script we can add
- 00:38:37 the async data method
- 00:38:40 now you might know the normal data
- 00:38:43 method from your
- 00:38:44 old view apps data was
- 00:38:47 a property a method where you return
- 00:38:50 an object which holds data with which
- 00:38:53 you want to
- 00:38:54 initialize your component and i could
- 00:38:57 hard code my recipes in there
- 00:38:59 nothing wrong with that however in next
- 00:39:02 apps which
- 00:39:03 are server-side rendered you get async
- 00:39:05 data as well
- 00:39:07 async data is a special method
- 00:39:10 it's comparable to the normal data it
- 00:39:13 also initializes your component with
- 00:39:15 some data
- 00:39:16 but async data is actually executed on
- 00:39:19 the server as well
- 00:39:21 so if you're in single page mode and
- 00:39:22 you're clicking around it's executed
- 00:39:24 with each click
- 00:39:25 on the client but if you're sending a
- 00:39:28 request
- 00:39:29 for a page for the first time as
- 00:39:32 explained at the beginning of this video
- 00:39:34 then you will actually execute the code
- 00:39:36 on the server
- 00:39:37 to fetch all the data which needs to be
- 00:39:40 rendered on the page
- 00:39:42 in advance on the server before
- 00:39:44 returning the page
- 00:39:46 so that you can pre-render the page with
- 00:39:49 the data
- 00:39:50 on the server and send back the finished
- 00:39:52 page to the user
- 00:39:54 and in this example here i won't reach
- 00:39:57 out to a server
- 00:39:58 i will still hard code some some well
- 00:40:01 code in here
- 00:40:02 but you could simply replace this with
- 00:40:04 an axis call or whatever
- 00:40:06 ajax library you want to use so you
- 00:40:09 could install
- 00:40:10 axias import access and then make a get
- 00:40:13 request
- 00:40:14 and the important thing is if you have
- 00:40:16 something like a promise like here for a
- 00:40:18 get request
- 00:40:20 you should return it and next will
- 00:40:22 automatically wait for this promise to
- 00:40:24 be resolved
- 00:40:25 take the results value and take it if
- 00:40:28 it's an object which
- 00:40:29 should be as the initial value or the
- 00:40:32 initial data for this component
- 00:40:34 now here i'm not using access and i'm
- 00:40:36 not using a server but i want to show
- 00:40:38 this
- 00:40:39 still so i will simply create a new
- 00:40:41 promise on my own
- 00:40:43 as you probably know a promise takes a
- 00:40:45 function as an argument
- 00:40:47 where we in turn have two arguments
- 00:40:50 reject and excuse me resolve and reject
- 00:40:56 and you execute these inside of the
- 00:40:57 promise to either resolve or
- 00:40:59 reject it now here i will use the normal
- 00:41:02 set timeout method and set a timeout to
- 00:41:05 let's say one and a half seconds and
- 00:41:08 after that
- 00:41:09 time this arrow function here will get
- 00:41:11 executed
- 00:41:12 and in this arrow function i simply want
- 00:41:14 to resolve some data and
- 00:41:16 this is really just some code i use to
- 00:41:18 fake an asynchronous
- 00:41:20 request to fake that we would fetch this
- 00:41:22 data from a server
- 00:41:24 so in there i resolve a javascript
- 00:41:26 object with let's say a recipes property
- 00:41:29 the name is up to you which might be an
- 00:41:32 array
- 00:41:32 and in that array i want to have my
- 00:41:34 objects and again this is really just
- 00:41:36 some dummy data
- 00:41:37 which you normally of course would fetch
- 00:41:39 from a server
- 00:41:41 now in there you might have an id could
- 00:41:43 be anything could be a number a long
- 00:41:45 string
- 00:41:46 something like this here and you will
- 00:41:48 have a tea title
- 00:41:50 so here i will use the delicious pizza
- 00:41:52 title
- 00:41:54 you will also have your preview text of
- 00:41:56 course
- 00:41:57 which is a string so here i will also
- 00:41:59 use the preview text from above
- 00:42:02 and you will have your thumbnail
- 00:42:06 like that so let's grab this thumbnail
- 00:42:09 link then now of course we have two
- 00:42:13 recipes here so let's also enter the
- 00:42:16 second one
- 00:42:18 there i will grab the title which i hard
- 00:42:20 coded into my template
- 00:42:22 from the template i will also grab the
- 00:42:24 hard-coded preview text
- 00:42:27 and i will also grab the hard-coded
- 00:42:30 image url so now this is all
- 00:42:34 coming as it would come from a server
- 00:42:37 in the form of a javascript array and
- 00:42:39 since i returned that promise in async
- 00:42:41 data
- 00:42:42 next will wait for this promise to
- 00:42:44 resolve or to fail
- 00:42:46 and will then merge the data which you
- 00:42:48 resolve so this object
- 00:42:50 with the data your component has anyways
- 00:42:53 now here we
- 00:42:54 don't have any other data we could have
- 00:42:55 and it would be merged
- 00:42:57 here however this will be our entire
- 00:42:58 component data the key thing is
- 00:43:01 in our template we can use that data
- 00:43:04 because the template will only be
- 00:43:06 rendered once this fetching is done
- 00:43:08 so there will be a recipes property
- 00:43:10 which we can reference in our
- 00:43:12 template that means we can remove the
- 00:43:14 second
- 00:43:15 recipe and for the first one i'll use
- 00:43:18 v4 and loop through all my recipes
- 00:43:22 in the recipes property so recipe here
- 00:43:26 the name that is up to you you can name
- 00:43:28 this whatever you want could be r
- 00:43:29 could be recipe recipes here however
- 00:43:33 is coming from the data of that
- 00:43:35 component and in our case
- 00:43:37 that has to be recipes because we get
- 00:43:39 back an object with a recipe's property
- 00:43:42 which will become our component data
- 00:43:44 eventually
- 00:43:46 so now we also should assign a key and
- 00:43:48 here we'll just use recipe id
- 00:43:51 each recipe has an id don't forget
- 00:43:54 and now we can really just bind all
- 00:43:57 these values
- 00:43:58 to the dynamic values we're fetching so
- 00:44:00 in this case to recipe
- 00:44:02 thumbnail referring to that thumbnail
- 00:44:05 property we added
- 00:44:06 and the same of course for title and
- 00:44:08 preview text so for title
- 00:44:10 it's recipe title and we should bind it
- 00:44:13 dynamically therefore
- 00:44:15 for id it's recipe id
- 00:44:18 and for preview text it's there for
- 00:44:23 recipe preview text like that
- 00:44:27 if we now save all files and we reload
- 00:44:29 this page
- 00:44:31 we should still see our recipes however
- 00:44:33 if we reload
- 00:44:35 it takes one and a half seconds because
- 00:44:38 this is pre-rendered on the server you
- 00:44:41 can best see it if i open
- 00:44:42 my url bar and i click the refresh icon
- 00:44:45 you see it spins and spins and here the
- 00:44:47 data is
- 00:44:48 because it waits for this promise to
- 00:44:50 resolve
- 00:44:51 now let's fake the same on our
- 00:44:55 detail page so i'll copy the async data
- 00:44:59 function here and add it to a script
- 00:45:02 in the id index.view file
- 00:45:06 so there i'll also add async data also
- 00:45:09 have a promise to
- 00:45:10 fake a real request where we get data
- 00:45:13 and here of course i resolve
- 00:45:16 a single recipe so i resolve an object
- 00:45:19 which will become my component data
- 00:45:21 which just has a recipe property and
- 00:45:24 that should be the recipe we loaded
- 00:45:26 so here of course we got two
- 00:45:30 possible recipes we could fetch the one
- 00:45:32 with id1 which is the delicious pizza
- 00:45:34 and the other one
- 00:45:36 and to make this simple because i don't
- 00:45:39 send a real request
- 00:45:41 to a server where i could send my route
- 00:45:44 parameter the id
- 00:45:45 to the server to only get back one
- 00:45:47 recipe
- 00:45:48 i will actually keep the full original
- 00:45:50 code where i get both recipes
- 00:45:53 but i want to filter
- 00:45:56 for the recipe which matches
- 00:46:00 my route id so
- 00:46:03 i will still only get a recipe here but
- 00:46:06 i got
- 00:46:07 an array here to which i will chain the
- 00:46:10 find method
- 00:46:11 a default javascript array method
- 00:46:14 find takes a function as an argument
- 00:46:17 which will be executed
- 00:46:19 on every object or element in that array
- 00:46:22 in this case
- 00:46:23 two elements so it will then execute
- 00:46:26 this function
- 00:46:27 with each element and receive that
- 00:46:29 element as an input to the function
- 00:46:31 and you should return true if that is
- 00:46:33 the element you wanted to find
- 00:46:35 and it will then return this element so
- 00:46:37 recipe will only be one of the two
- 00:46:39 elements here
- 00:46:40 i want to return the element where the
- 00:46:42 id each element has an id property don't
- 00:46:45 forget
- 00:46:46 is equal to the id we entered in our url
- 00:46:51 now in async data we actually can't
- 00:46:53 access dollar sign
- 00:46:54 route because the view component hasn't
- 00:46:56 been fully loaded yet
- 00:46:58 and hence this has not been made
- 00:46:59 available yet
- 00:47:01 but in async data you get a special
- 00:47:03 argument passed into by nax
- 00:47:05 js the context
- 00:47:10 argument context has a couple of
- 00:47:13 convenience
- 00:47:14 properties holds a lot of useful
- 00:47:16 information you can find a link to the
- 00:47:19 api documentation in the video
- 00:47:20 description and in this case
- 00:47:23 context has a params property which
- 00:47:25 holds
- 00:47:26 the params it can parse from your url
- 00:47:30 in this case i'm interested in the id
- 00:47:31 param and only if that matches
- 00:47:34 the id of an object here in the array
- 00:47:36 this will be returned as the recipe
- 00:47:38 which was loaded
- 00:47:40 so now i can output that here i can
- 00:47:42 output
- 00:47:43 recipe title here and here
- 00:47:46 i don't just want to have the preview
- 00:47:48 text but the full description text
- 00:47:50 so let's quickly add a new property to
- 00:47:52 both objects
- 00:47:54 description text this is
- 00:47:58 really a delicious meal
- 00:48:01 and yes it's the same text for both
- 00:48:03 recipes but just for demo purposes
- 00:48:06 so now we can output that here in the
- 00:48:08 paragraph we can output
- 00:48:10 recipe description text
- 00:48:13 and for the image i want to bind this
- 00:48:16 dynamically
- 00:48:17 to recipe thumbnail
- 00:48:20 and alt could also be bound dynamically
- 00:48:23 to recipe title
- 00:48:29 now if we reload that page
- 00:48:32 we got our recipe here with a rather big
- 00:48:35 image so
- 00:48:36 maybe we can do something about the size
- 00:48:38 here
- 00:48:39 recipe image as a class can be added to
- 00:48:41 the image
- 00:48:43 and now we can go down to the size and
- 00:48:46 style the recipe image here
- 00:48:48 in the styles to get it i give it a
- 00:48:50 width of 100 percent
- 00:48:51 and maybe see how that looks like
- 00:48:58 it's still very big but this is fine in
- 00:49:00 my opinion for a starter
- 00:49:02 now this is the delicious pizza and if i
- 00:49:04 go back
- 00:49:07 and i load the seafood salad it still
- 00:49:10 takes one and a half seconds because
- 00:49:12 async data has that promise which
- 00:49:14 resolves only after one and a half
- 00:49:15 seconds
- 00:49:16 and then i see the seafood salad looks
- 00:49:19 very good
- 00:49:20 to me so now this is a very simple
- 00:49:23 recipe page and you always see that
- 00:49:25 waiting time because we're faking that
- 00:49:27 http request we're doing which runs
- 00:49:29 either in the client if we're clicking
- 00:49:31 around
- 00:49:31 or on the server if we enter a url for
- 00:49:34 the first time
- 00:49:35 with that we get a very basic next
- 00:49:38 application
- 00:49:39 showing its core features server side
- 00:49:41 rendering
- 00:49:42 and also the you configure folders and
- 00:49:46 files
- 00:49:46 and i will give it give you the rest
- 00:49:48 approach now to finish this
- 00:49:51 very basic app up i'll add a second
- 00:49:54 component in the components folder
- 00:49:56 and this will be my header.view file to
- 00:49:58 have a little navigation bar
- 00:50:00 there i will just add a template with a
- 00:50:02 header component
- 00:50:03 and in there i'll have a nav component
- 00:50:06 with an unordered list with two list
- 00:50:08 items
- 00:50:08 in each list item i want to use a next
- 00:50:11 link
- 00:50:12 the first one goes to the starting
- 00:50:16 page the second one goes to my recipes
- 00:50:23 and actually i guess we have a third one
- 00:50:25 to the about page
- 00:50:27 and now we add the tool link to all of
- 00:50:30 them
- 00:50:30 now for the first one it's just slash
- 00:50:33 for the starting page
- 00:50:35 for the second one it's recipes and here
- 00:50:37 it's slash about
- 00:50:38 referring to the index.view file for
- 00:50:41 just slash
- 00:50:43 to recipes index.view for slash recipes
- 00:50:48 and to about index.view for slash
- 00:50:52 about now of course we need some styling
- 00:50:55 here
- 00:50:56 so let's add some scoped styling here to
- 00:50:58 style our header appropriately
- 00:51:01 maybe make sure that it has a width of
- 00:51:04 100 percent
- 00:51:06 um a height of
- 00:51:09 30 pixels maybe
- 00:51:12 let's set display to
- 00:51:16 flex and center everything with justify
- 00:51:19 content center
- 00:51:20 and align items center
- 00:51:24 and let's then also add some styling to
- 00:51:26 the unordered list let's set the list
- 00:51:28 style
- 00:51:32 to none remove all padding and
- 00:51:35 margin and also give it a display of
- 00:51:38 flex
- 00:51:38 to position the individual links next to
- 00:51:41 each other
- 00:51:42 by also adding justify content and then
- 00:51:45 maybe
- 00:51:49 center to and align items also centered
- 00:51:54 and then let's go to the list items
- 00:51:56 themselves
- 00:51:57 and let's each give a margin of zero to
- 00:52:00 top and bottom but 10 pixels to left
- 00:52:03 right to get some spacing between the
- 00:52:04 items
- 00:52:06 and now let's use that header and now
- 00:52:08 here's a special trick
- 00:52:09 we could include it in any page but of
- 00:52:12 course
- 00:52:13 all these pages should share the header
- 00:52:15 and that is where
- 00:52:16 layouts come into play each next page is
- 00:52:20 loaded into this default layout in the
- 00:52:22 position of this
- 00:52:23 next hook here and you can also set up
- 00:52:25 some general
- 00:52:27 app styles in the default view file i
- 00:52:29 will keep the ones which were set up but
- 00:52:31 you can of course
- 00:52:32 set this to your settings or clean it up
- 00:52:35 the thing is you can add a script
- 00:52:38 section in this layout default.view file
- 00:52:41 too
- 00:52:42 and by the way you should keep that file
- 00:52:44 because default.view is something next
- 00:52:46 will look for
- 00:52:47 as the default layout you guessed it
- 00:52:50 and in here i will import my header
- 00:52:53 from
- 00:52:56 add slash components header
- 00:53:02 and i will then add components here
- 00:53:05 header like this and add my header with
- 00:53:08 a capital h to not use the default
- 00:53:10 header
- 00:53:11 here now if you save all files you get
- 00:53:14 the header at the top
- 00:53:15 and you can indeed navigate around to
- 00:53:18 the different pages
- 00:53:21 now just saw the about page can use some
- 00:53:24 styling let's add some styles here too
- 00:53:27 and simply set some text alignments
- 00:53:32 here for the h1 tag but the core thing
- 00:53:35 is now
- 00:53:36 we got our nice header we can give it a
- 00:53:39 background color of maybe
- 00:53:42 five two one seven five one
- 00:53:46 like this and now also style our
- 00:53:50 anchor tags here in our header
- 00:53:54 to have a text decoration of non
- 00:53:59 and color of white maybe
- 00:54:03 so this looks now much better and now
- 00:54:05 with that
- 00:54:06 we have an application where we can
- 00:54:09 navigate around
- 00:54:10 get a header on each page and where we
- 00:54:12 take advantage of the core features of
- 00:54:15 next
- 00:54:16 clearly this is not the most beautiful
- 00:54:18 application you ever built
- 00:54:20 and clearly next has to offer way more
- 00:54:22 than that
- 00:54:24 but these are the core basics which i
- 00:54:26 wanted to show you
- 00:54:27 and i hope that this helps you getting
- 00:54:29 started with next
- 00:54:30 now if you want to dive deeper you may
- 00:54:32 have a look at my more
- 00:54:33 thorough introduction course on udemy or
- 00:54:36 additionally
- 00:54:37 at the really good official nux
- 00:54:39 documentation
- 00:54:40 which you can find are noxjs.org
- 00:54:43 there you find details about all the
- 00:54:45 different features how to use and
- 00:54:47 configure them
- 00:54:48 and also about features which i didn't
- 00:54:50 show in this video
- 00:54:52 i hope you got started with that video
- 00:54:54 though and i'd of course be more than
- 00:54:56 happy to welcome you in future videos
- 00:54:58 too
- 00:54:58 hopefully see you there bye