I am confused about writing a Next.js application which will render the pages server-side when I have reusable components and <Link>s to navigate to other areas of the application.
The documentation says
getInitialProps(SSR) is only called for pages, and not called for components"componentWillMountis not executed server side, its client-side rendering only<Link>tag is only client side navigation therefore "pages" it navigates to are rendered client side
My questions
I am unclear on the following:
- How to break up your application into reusable components keeping server-side rendering?
- If there are
<Link>s to other pages of the application, how can the other pages be rendered on the server? - If
<Link>s are client side, surely this means only the initial page will be rendered server-side, so what is the point of writing an app in Nextjs rather than plain React? - If
getInitialPropsis only called for pages, surely this means that the page'sgetInitialPropshas to do all the server calls for any data rendered on its page and then send to child components, and this must be very slow. If a page contains a list of items, there is going to be one server call to get the list of items, and for each item in the list there will need to be a call to get the items details and another call to get the items image. This is a lot of server calls before the page is rendered.
My application
I thought it would be easier to illustrate my issue with a sample application of the sort of things I want to be able to do.
- My application has several pages: Tab-1, Tab-2, Tab-3, Tab-4 and details pages for items listed in Tab-1 and Tab-2 etc.
- Each page in my application has the same layout, a header area, a tab bar, the page's content and a footer
- On clicking items in the tab bar you can navigate to the other pages in my application
- Each tab contains a list of items of different categories, clicking on an item in the lists takes the user to the details "page" for that item
Here is a graphical representation of my application.
Project structure
All pages use layout-template to add the main structure of header and footer and then adds its own content in the middle of the page using components
|- pages
|- index.js (i.e. tab-1)
|- tab2.js
|- tab3.js
|- tab4.js
|- aitem
|- [id].js
|- numitem
|- [id].js
|- Components
|- layout-template.js --- needs data to pass to header/footer
|- header.js
|- footer.js
|- AlphabetList --- needs data
|- AlphabetListItem --- needs data
Below are samples of my components showing how they make up my application. See in some of the components they have to get data from the server.
As they are components they are getting their data in componentWillMount, which means that component will not render server-side. Therefore this seems to completely defeat the purpose of writing Next.js.
Component = layout_template.js needs to get data from the server to pass to header and footer
Component = header.js just contains JSX
Page = Index.js (URL= "/" or "/index") doesn’t get any data from the server, just specifies JSX
Component = AlphabetList.js gets the list of alphabet items from the server and renders it using another component
Component = AlphabetListItem.js gets the item's image from the server then renders it. On clicking on this component the app goes to the item's details page
Page = AlphabetItemDetails.js ( URL = "aitem/[id]") gets additional information about the item from the server and renders fill details of the item
How do I structure my code?
- For the main layout/header/footer to render server-side, do I have to duplicate the code to get the logo in the
getInitialPropsin every page? i.e. in index.js, tab2.js, tab3.js, tab4.js,aitem/[id].jsandnumitem/[id].js? This seems to go against any decent code design of not duplicating code and instead pull into reusable code. - For all the data in a page to be rendered server-side, do I have to get all the list items and then get each items details and image URL in the
getInitialPropsof the page?






