Currently setting up a Server Side Render (SSR) application is a pain in nodejs. There are many scaffolds available for nodejs. But it comes with its own tech-depth and learning curves. This also includes hidden configurations of Webpack.
All in all, when you give Webpack a chance, your encounter will rarely be a pleasant one.
If I say, you can build an entire SSR without setting up installing any external nodejs dependency. Would you believe it? I guess
However, In this tutorial, I will explain how to set up a simple SSR app without installing a single nodejs library or bundler. That also including a hydrate react app(isomorphic app).
Don’t be afraid, To do things differently, we will not install any nodejs libraries. However, I still like npm as a task runner. So let’s use it. Create a folder SSR and init npm package.json
Add Basic deno server: Create
server.tsx a file and add below code
We will use oak module here to create Deno server. You can create your own server. For that read my article Creating Routing/Controller in Deno Server(From Scratch)
Add below command in
Now we can run the application and verify on
Now we can run the application. Let us add our first rendering code. For that, we need to ReactJS. Since Deno uses ES Module import, We will use the CDN hosted version of react and react-dom. For that, there is a good CDN provider https://jspm.org/.
Now since we are going to write some TSX syntax(typescript JSX). We have to change the file extension of
server.tsx. Let’s do that and update
Add below lines in
Run the app again. You will see errors on the console.
TS7026 [ERROR]: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
This error is due to missing typings to react. Since we do not include types to react. We have to let know the typescript compiler. How it should treat JSX(TSX) syntax.
To suppress these errors, Add below lines.
Now run the server again. You can see your first
React SSR running on the browser. Nice!
Let’s move further and start adding a few core features for Server. Let’s add some server-side data for our app. For that, we will include a few routes on Oak Server. Oak
Here in the above code, We have created three routes.
/todos/to get a list of the todos
/todos/:idto todo by id
/todos/create a new todo
function init() to create some initial dummy todos. You can use postman to try-out get and post data.
Since now we have API to create todos and consume todos. Let’s list down all this on our react app. For that add the below-mentioned code.
Update all the changes and run the app. You will see a list of Todos containing two rows of initial data. You can use curl post data to route
POST/todos/ to create new records. Once you add a post, refresh the page, You will see added new post data.
If you noticed, I have added basic bootstrap to make UI nicer. You can use some other CSS library.
Tada! Now you have running the SSR app. You can replace the in-memory todos store to any persistent database. The result will be the same.
Now time to add some interactive behavior in Our react app(
client-side). But before doing that, let’s move our react code to some separate file
Create a file
Notice the change in the App component. Since we do not have direct access to todos now, We need to pass data as props while rendering it. Corresponding changes have been done for ListTodos.
Run the app and see changes on the browser, If all good there will be no change in the final output.
Once you do the above changes and try to delete by clicking on cross-button. You will see no change in UI. By code, it should turn the element color to red. So what could be the reason for that?
Since we are using
ReactDomServer.renderToString the library which converts React app to string. So we lose all JS capabilities. To re-enable react js on the client-side. For that React provides you Hydrate module(API). This hydrate API re-enable the react feature on the client-side again. This makes our app Isomorphic app. More: Hydrate
Adding hydrate is a tough task to do. But Awesome Deno shines well here too. Deno provides Bundle API to convert a script to js. We will use
Deno.bundle to create hydrate js for the client-side.
Create a new file
client.tsx and add below codes:
Add below codes to compile and convert
client.tsx to serve as a route in our server.
Since we are using unstable API
deno.bundle, You have to update
package.json and add more flags. Same time, We are using DOM with typescript. So we have to add custom
You can use bundler as CLI to convert
client.tsx before even starting the server. However, I just wanna show a cool way of doing it. So I use
Deno.bundle on runtime.
Once you do all the above-mentioned changes, Re-Run app. You will notice the list is the visible and hidden same time. This is because we react hydrate start working and it is trying to re-initialize the app. So all the data we render from the server is gone to persist data we need to pass data as application initial data. There are a lot of patterns to pass initial data. We will use the simple window global data.
Let’s start data on the window after making below changes on the given files.
After the changes, all the files will look as below.
Now you have a running, working SSR/Isomorphic App that is fully written in Deno. We didn’t use any nodejs/npm modules or WebPack.
Thanks for reading this tutorial. Please follow me to support me. For more of my work, check-out my website https://decipher.dev/.
Hope you like this tutorial, Please follow me and clap for me on medium: isomorphic-application