We have a simple app.tsx file. We will bring in React, the style function from TypeStyle. Then we create a CSS class name using TypeStyle's style function, setting up the color to be red, and font size of 30 pixels as a demonstration.
We will also go ahead and create an app component for React. We will simply return a div with the class name pointing to this TypeStyle-generated class. Within the div, we'll simply log out the text, "Hello World."
Let's create a simple server to pre-render this component and its CSS, and return it as an HTTP response. I'll go ahead and install Express and the type definitions for Express. I'll save these to our dependencies.
Once the installation is complete, we will go ahead and create a server file as server.tsx. We will bring in React and ReactDOMServer for pre-rendering HTML server-side. You will also bring in the getStyles function from TypeStyle for pre-rendering the CSS.
We will bring in the app component, which is the component we want to render server-side. We will bring in express, which will be used to power our HTTP server. We will go ahead and create a utility render page function, which will take some HTML and some CSS, and return a rendered index.html content as a string.
Our main HTML page contains HTML with the head tag containing the style tag with an ID styles target, which will contain all our server-side rendered CSS. After the head, it has a body tag with a root div of ID root, which contains all our server-rendered HTML.
Finally, our index page loads a client-side script, bundle.js, which will rehydrate the style target and the root div. We will create our HTTP server using Express. We will add a root handler to return our index page. Within our root handler, we will pre-render the HTML using ReactDOMServer.renderToString, passing in our app component.
We will get all the server-collected styles using TypeStyle's getStyles function. Finally, we will send the response by rendering into the page this HTML and the CSS. To serve our client bundle.js file, we will simply serve up the public folder using express.static.
Finally, our application will listen on port 3000, and once it starts, it will log out the message, "App listening on port 3000." The bundle.js file in our index page is being generated using webpack. Webpack is configured using the webpack.config.js file. The output section of our config is writing bundle.js to the public folder.
Our application entry point in the config points to source at main.tsx file. Let's go ahead and create this main.tsx file, which will be our client-side entry point. We will bring in React and ReactDOM for hydrating the HTML. We will bring in TypeStyle for hydrating the CSS. We will also bring in the root app component, which is what we want to hydrate.
We will use ReactDOM to render the app component to the document root div. To hydrate the CSS, we will set TypeStyle's styles target to the style tag in the document head. To demonstrate this project, we have a style target in our baggage.json that runs webpack to generate our bundle.js, and then starts the server by running our server.tsx.
We jump back to the terminal and run npm start. This kicks off webpack, which will generate our public bundle.js file. Then the Express server starts listening for requests on port 3000. If we open up our browser on localhost:3000, you can see that the application works as expected.
If you look at the network tab in our development tools, the HTML and CSS was pre-rendered on the server and sent as a part of the original response. It was then rehydrated by bundle.js on the client. Now the DOM contains the rehydrated style and the root div.
To recap, we created our styles and React components, rendered them on the server and sent them down as a part of the response, then finally rehydrated them on the client.