Contentful server side rendering dynamic routes in Next.js? - next.js

According to Next.js, to render a dynamic path you need both getStaticPaths() and getStaticProps() the problem with this for me is, the data of the page is being cached. I'm using Contentful for my page data, but when I make an update in my post the update doesn't make it to the page. I have to re-compile and push to my production in order for the change to take place.
However, for non-dynamic routes I can use getServerSideProps() and it works no problem.
I know with SWR you can render client-side, but with updated data.
Is there a way to render the Contentful data in a dynamic route during run-time with SWR rather than using Contentful's client.getEntry ?
Thanks!

You only need getStaticPaths and getStaticProps for dynamic routes if you want them statically generated at build-time (SSG). You can use getServerSideProps instead on your dynamic routes if you want the data fetched at runtime - there is no issue with that, especially since you are already doing that for other pages.
See this section of the documentation that mentions using dynamic routes with getServerSideProps.

Related

Next.js blog with comments build strategy

I am trying to get my head around Next.js and the docs talk about a range of data fetching methods. They suggest static generation is ideal for a simple blog, with benefits over client-side rendering and server-side rendering. I was wondering how to add a comments section to a blog. I would like to hear the thoughts of those more familiar with Next.js.
Could a blog post still be rendered statically and then a comments section component within the page fetches comments data on the client-side or server-side at the time the page is requested? Or would the whole page (post+comments) have to be rendered using either the server-side or client-side rendering strategy?

best practice for conditional rendering with SSR in Next.js

in my Next.js app i want to render a mobile-/ desktop-header based on the width of the device. In general this is a simple task, i did many times in normal react, using hooks like useWindowDimensions, where I check the width of the window object and use this parameter for a simple condition.
In Next.js however I ran into the problem, that my app is pre-rendert on the server, so of course there is no window object, that I could use for the condition.
Things I tried:
dynamic import of the component, this means the component didn't get pre-rendert on the server, but only on the client. This would work, but I didn't use the benefit of SSR, and for SEO reasons I want to pre-render "key-components" like the header.
I just picked a condition for SSR like render always the mobile-header for example and on the CSR I just render on the real condition. This would solve my issue with render always "key-components" on server side, so SEO is happy, but i run in an ugly warning about content mismatch between server and client, because when I render the app on desktop device, my first render on client side of course would be the desktop-header. So this doesn't seem to be a good solution either.
Next I tried to render a certain condition like before, so render always the mobile-header on server AND client side and use a useEffect hook only on mount useEffect({...}, []) which then check the real condition and trigger a re-render with the correct condition. This would solve my SEO-thing, and also the ugly content mismatch warning. BUT I run into a noticeable layout-shift, where the user sees the mobile-header first and after half a second the header changes to the desktop-header. ugly stuff..
So I got my next idea, which was checking the user-agent or device type with getServersideProps and somehow use this info for a conditional rendering on server-side. This doesn't really work out to well, specially I would want to use it in my _app.tsx so I don't have to write this stuff for every page again and again. In a discussion thread in the official Next.js repo I found, that getServersideProps doesn't work in _app.js yet, only getInitialProps, which is deprecated, and shouldn't be used anymore...
So, to make things short, there has to be a good way to render components in Next.js without the above problems. I just couldn't figure out yet, what is best practice for this kind of stuff.
I would appreciate any hints, tipps or advices in this topic ❤️

How to create reusable components in Next.js

I am not sure if I am missing something within the Next.js documentation, but it seems as if it is unfeasible to reuse components within a Next.js application without breaking the component.
So from my understanding:
Next.js uses SSR to fetch data at a pages level by either getStaticProps, getStaticPaths or getServerSideProps.
Once this data has been fetched it is returned to the page via props.
The page then has access to the props and can then handle this data however it wants.
In order to use the SSR techniques for child components of our page we have to grab the child components data at page level and then pass this data down to our components.
This raises some concerns for me and questions:
This means our children components always have a dependency on the parent page?
We can't reuse our components on other pages without repeating logic or breaking components?
How do I reuse components without client side rendering?
Could I just grab everything at the entry point of the app and then store this in various state variables using Redux and call them at component level when needed?
By using client side rendering it sort of defeats the purpose of using Next.js. Yes, I can just use a useEffect hook to grab the data at component level but this doesn't seem right to me.
Am I missing something in the architectural pattern or is this just a vulnerability when working with Next.js?
The more I think about this the more I realise Relay and GraphQL are the future.

Passing Data between APIs and Database with React

I am creating a project but very new to React and async programming. I am using React to display users email via an API.
I can get all the email data via ComponentDidMount calls to the API. It displays them correctly and I can get subject,body etc. Now, I need to send the body of the currently selected email via a button to my back-end side, do some work with it (compare strings to database etc) and then fetch back the result and display it in a div. What would be the best way to go about it?
I couldn't find any good answers to this from google.
Should I have gotten emails and done all that work all server side first somehow before fetching both the body and the result along with it with React? Or is there a way I can send the current body string out to my controller, do the work and then get the result back all in async?
Thank you in advance!
Although this question is too vague to answer but I know what you're coming from and I want to give you some ideas about the general structure of a React-related project:
The backend side should be designed to Restful Api Endpoints.
Use Redux to manage frontend (react) application's state.
Use Redux-thunk (or Redux-saga) to manage side-effects (call api)
In componentWillMount or componentDidMount, use Redux dispatch to dispatch an action to Redux then use Redux-thunk (or Redux-saga) to call api and update application's state.
The component which is connect to application's state will be updated based on state's changes.
It's long way to go but hey, that's what all of us have to go through. Good luck!
PS: If any terms are not familiar with you, do some google-ings.

why does twig's render function create a subrequest

why does twig's render function create a subrequest ? Why dont they just render the response and send it as part of the response ?
Also I can see that the rendered response appears in the browser just after the main template shows up. How does it happen ?
I created an answer on Stackoverflow which basically goes through the different alternatives of the render function.
It also explains why you should be using the render function over a regular include.
I'd advise you to read the chapter about embedding controllers in Twig. An interesting quote from the doc about when you should consider using the render function:
Whenever you find that you need a variable or a piece of information that you don't have access to in a template, consider rendering a controller.
TL;DR
By default, the render function only takes a URL (either absolute or relative).
By analogy it is like getting HTML through ajax and injecting it in the page: one request that queries a controller to get some HTML which get injected it into the page.
There are different render calls like render_esi (for support of the ESI tags) that have their own rendering strategies. If you start with the inline rendering (through the default render function) you will have the opportunity later on to use other rendering strategies without refactoring your code.
The render function is meant to scale your application.
For more details about its usefulness, let's look at the render_esi function.
With the render_esi function you can implement ESI tags to use with Varnish.
(There are other solutions than Varnish but it's among the most popular ones)
Varnish is a caching solution that is located between your web servers and the users. Varnish will filter the response from your web servers, cache the entire page then look for these ESI tags.
If Varnish cached your page for a day but the render_esi function are set to be cached for 2 hours, Varnish will only query (through a URL when the cache expired) for these specific render calls instead of the entire page (which is why render_esi do sub-requests) and replace parts of the template with the sub-requests' response.
Caching in general is very interesting and very broad so it's hard to go over every details in my answer but I hope my answer will help you.
Caching (or cache) according to Wikipedia:
In computer science, a cache (/ˈkæʃ/ kash)[1] is a component that transparently stores data so that future requests for that data can be served faster.
Render is used when you not just want to include another template snippet, but also want to execute specific businesslogic, that belongs to this template. Or in other words: When include just isn't enough, you use render.
Because render doesn't only include a template, but also executes controller logic, it is encapsuled as a subrequest.
Imagine you want to display the latest news in a box on every page of your website. If you want to solve this with an include, you would have to fetch the latest news in each of your actions and pass it to your template.
But if you use render, you just write one action for this, and put a render tag everywhere in your templates where you would like to have that news box. The render tag executes the associated controller action, renders the response, and injects it into your current template.
Because I suck at explaining, you might also want to read this part of the symfony doc: http://symfony.com/doc/current/book/templating.html#embedding-controllers
In my opinion, answer should sound like this:
Controller is pretty simple "unit" which receives request and sends response.
Creating sub request for rendering controller gives you more power (flexibility).
About flexibility. Look at your controller, just like it just receives request and sends response and for example, you want to somehow filter request or decorate response? Where will you put this logic? Of course, at event listeners which can use other services to solve this task.
For example, I often use parameter converters for my controllers (it's not about good design, just for example). So how can I use "render", with specifying just id of my entity, to render only controller without creating sub request?
If you really want just to render some data you can use "include" or create an extension. Or you can create extension to render controllers without sub request, but think about it carefully, because further you can add more logic to filtering response and so on.
I can be wrong, it's just my opinion ;)

Resources