Published on
6 min read

Remix vs Next.js - Server Side Rendering (SSR)

Part 1 - Server Side Rendering
Authors
  • avatar
    Name
    John Moscarillo
    Twitter

Server-Side Rendering (SSR) is a technique that enables web applications to render web pages on the server-side before sending them to the client-side. This technique improves web application performance, increases search engine optimization, and improves the user experience. Both Remix and Next.js are popular web frameworks that support SSR.

In this comparison, we will take a closer look at how Remix and Next.js implement SSR and their differences.

Server-Side Rendering with Next.js

Next.js is a React-based web framework that supports server-side rendering out of the box. With Next.js, you can create server-rendered React applications that load quickly, even on slow networks. This makes your web application more accessible to users, as they don't need to wait for the client-side JavaScript to load before seeing the content.

Next.js achieves SSR by providing a unique rendering mechanism called Static Generation (SG) and Server-Side Rendering (SSR). Static Generation generates HTML pages at build time and serves them to the user when requested. This is great for content-heavy pages, like blog posts, that do not need to be dynamically generated on every request.

Server-Side Rendering, on the other hand, generates HTML pages on the server every time a request is made. This is useful for pages that have user-specific content or rely on external data sources. With Next.js, you can choose to use either Static Generation or Server-Side Rendering, or a combination of both, depending on your application's needs.

Next.js also provides a built-in data fetching system that allows you to fetch data from external APIs or databases before rendering the page. This can be done on the server-side, client-side, or both. By fetching data on the server-side, you can reduce the time it takes for the page to load and improve the user experience.

To fetch data on the server-side, you can use the getServerSideProps method. This method runs on the server-side and fetches data before rendering the page. The data is then passed as props to the page component.

Here's an example of how getServerSideProps can be used to fetch data:

export async function getServerSideProps(context) {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();

  return {
    props: {
      data,
    },
  };
}

function Page({ data }) {
  return <div>{data}</div>;
}

export default Page;

In this example, getServerSideProps fetches data from an external API and passes it as props to the Page component.

Server-Side Rendering with Remix

Remix is a modern web framework built for server-side rendering with a focus on developer experience. Remix's core philosophy is that "everything is a component," which means that every part of a website is a reusable component that can be composed together to build a fully-functional website.

In Remix, the server and client are very tightly integrated, which allows for seamless hydration of client-side components. This means that when the page is first loaded, the server renders the HTML, and then when the JavaScript is downloaded and executed, the client-side components are hydrated with the necessary data to continue functioning as expected.

One of the key benefits of SSR in Remix is improved performance. Since the initial page load includes fully rendered HTML, CSS, and JavaScript, the time to first paint (TTFP) is greatly reduced. This means that users can start interacting with the website sooner, which can lead to increased engagement and conversions. Additionally, since the server is responsible for rendering the HTML, the browser has less work to do, which can lead to smoother animations and faster page transitions.

Another benefit of SSR in Remix is improved SEO. Since search engine crawlers typically do not execute JavaScript, CSR can lead to poor search engine visibility. SSR ensures that the search engine crawlers receive fully rendered HTML, which allows for better indexing and ranking in search results.

Finally, SSR in Remix improves accessibility. Since the initial page load includes fully rendered HTML, users with assistive technologies such as screen readers can immediately access the content of the website. This ensures that users with disabilities have equal access to the content and functionality of the website.

To implement SSR in Remix, developers can use the useRouteData hook to fetch data from the server and pass it to the components for rendering. This ensures that the components have the necessary data to render on the server and the client. Additionally, Remix provides a built-in json helper that allows developers to easily fetch data from the server.

In conclusion, SSR in Remix is a powerful feature that can greatly improve the performance, SEO, and accessibility of a website. With its focus on developer experience and component-based architecture, Remix provides a powerful and intuitive framework for building SSR websites.

// index.js

import { Router, Link, useRouteData } from 'remix';
import { json } from 'remix-utils';

export let loader = async () => {
  const data = await fetch('https://api.example.com/data');
  return json(await data.json());
};

export let action = async ({ request }) => {
  const body = new URLSearchParams(await request.text());

  // do something with the form data, like submit it to a database

  return json({ success: true });
};

export default function Index() {
  const data = useRouteData();

  const handleSubmit = async (event) => {
    event.preventDefault();

    const response = await fetch('/submit', {
      method: 'POST',
      body: new FormData(event.target),
    });

    if (response.ok) {
      console.log('Form submitted successfully!');
    } else {
      console.log('Error submitting form.');
    }
  };

  return (
    <div>
      <h1>Hello, Remix!</h1>
      <p>The data from the API is: {data}</p>
      <form onSubmit={handleSubmit}>
        <input type="text" name="text" />
        <button type="submit">Submit</button>
      </form>
      <Link to="/about">Go to About page</Link>
    </div>
  );
}