Reactivity with SolidJS

Server-Side Rendering with Solid Start

Ryan Carniato

Ryan Carniato

SolidJS Creator
Reactivity with SolidJS

Check out a free preview of the full Reactivity with SolidJS course

The "Server-Side Rendering with Solid Start" Lesson is part of the full, Reactivity with SolidJS course featured in this preview video. Here's what you'd learn in this lesson:

Ryan demonstrates Solid Start, a collection of plugins that enable both client-side and server-side rendering in SolidJS applications. Progressively enhanced elements like "Form" and "A" which work without JavaScript are also discussed.


Transcript from the "Server-Side Rendering with Solid Start" Lesson

>> Let's actually see these together in action. So I got one more demo. I'm gonna use StackBlitz again. We're actually gonna go a little bit different here I have this link/bare but for the sake of your sanity and time what we're gonna do is actually go /hackernews because we're just gonna jump straight through.

You can also do it by the CLI. And if you do the CLI, the prompts will ask you what sample project you wanna do, but we're gonna go straight to Hacker News so that we can generate our project straight from this is one of the coolest things about StackBlitz.

Even in a mono repo, you can pull example project straight out and get the latest version here. So let me introduce you to Solid Start or SSR framework and introduce you to one of my favorite demos of all time, which is Hacker News demo. I've built this demo in pretty much every framework.

So this is one that I am relatively familiar with. So, again, I wanna emphasize this right off the start here. This is just Vite again. I'm very excited about what we can do here with Vite cuz again in this case it's the Solid Start plugin, not just the plain Solid plugin.

But Solid Start plugin is just a collection of plugins and those plugins can be produced independently and can be used in any Solid project. But the truth matters Solid Start is a fairly powerful setup in that you can do client side rendering like we've been doing all day or you can do Server Side Rendering.

The default here is Server Side Rendering. So this is a Server Side Rendered app with client navigation. So when we load the page we initially loaded from the server and then as we navigate this is client side navigating between our stories and then we can go in look at, compressed some comments and basically have our application.

So the reason I wanted to show this off obviously though is I wanted to show off how routing works in Solid and kind of get a feel for the data loading APIs. Solid Start Project, instead of having index.HTML like we were looking at before, We bring our index HTML into the JSX.

It gives us just a little bit more control and you can see some default setup here where we have error boundaries and suspense kind of wrapping our app. End user and developers like yourselves could go in and put in your own suspense boundaries and error boundaries where you need to but this is a good sane default that means like if something happens wrong somewhere we'll catch it for you.

Or something is async like it's you loadings lazy route or something we have a default to handle this for you. In our case we just added a fall back here which shows this loading thing. Honestly, this app is so fast, probably on this network, you're never gonna actually see the loading state admittedly.

I don't even think I'm gonna, yeah, it's too fast. But this is just there in case anything goes wrong. Solids router can be configured using JSX. But I'm not gonna cover that today. Instead, I'm just gonna show you the convenience of file system based routing. And the way we do that is we actually take the routes component from Solid's router and then Solid Start provides a file routes component that as a way of injecting it.

You could define your own routes however you want, but you can make custom routes, but then you can just go give me the ones in the file system and inject them cuz kind of like switch and match. Arkham components can return anything in this case it's just returning a config of what routes you have.

Then there's these two files the entry client and the server not terribly relevant render, this is just kind of setting up stuff. If you want to make some middleware, you kind of inject it in here on the server. And on the client side, it is just literally kind of a mount call, which we alias this because Solid Start also works a client side rendering.

So if you're in client side, render mode equals render, if you're on server side rendering mode equals hydrate. So this is just a way of kind of clarifying that. But most of our work here is actually going to be in our routes directory, which is where the file system routing starts.

And we've got a couple conventions. I would say it's a cross between old Next.js, like previous Next.js, and Remix. Is kind of like our convention where we use things like ..., for Start routes, we use parameterized routes like this by using square braces. And we also use the convention for nested routing by using the file name the same name as the folder name.

This example does not have that. But just to kind of understand. This example is very simple in fact, there's only three pages we have a top level page that catches like all the top headlines in the nav and then we have individual pages for stories and users. I didn't highlight this on our route component earlier, but the NAV is out here outside of the suspence outside the file route.

So it never changes when we navigate. It just stays there, and then we only replace the content that comes in down below. So this is basically the layout of this project. So, I've also set up this library where I've got some APIs, and this is a bit of a mix match.

I've been putting this around for a bit. But it's a combination of Firebase Hacker News API, and then a proxy that does some nicer things where we don't have to fetch every single comment individually on the page. But essentially, you can kind of write your data layer kind of outside and kind of import it in.

And in this case we're using just fetch API essentially to get our data and a little bit of error checking and whatnot, and it will just fetch whatever URL we give to it. Okay, so the key part here is that With Solid's router you can configure those data functions in but with file based routing, we've kind of set up a convention where you can just go export const routeData.

And this function actually runs client and server. So in this case we're doing isomorphic fetch. So it works on both sides. But against a third party API, so it's fairly straightforward. And what you're seeing here is we're creating a resource that has our stories. And then we have the types for our data and then you we use the type of routeData to get our typed resources back out again.

So let me see here yeah and all that happens in this pages which show some page content here and then when there are stories sorry that's not what I'm looking for. When they're stories we iterate through each story and show that story with a for loop. That is basically the logic one thing you'll notice here is we do have the null checks in our template cuz our suspense doesn't throw and it doesn't block.

If you don't want things to continue you do actually have to like check if it's actually there. But what's interesting about this is it means that if you don't use suspense, all our primitives still work as well, it's just it's there mostly to coordinate the kind of loading and stuff for SSR like streaming.

We have out of order streaming for SSR. And this kind of pattern here is essentially how you build your apps. The other convention that we do with Solid and Solid Start quite often is that we use capital case versions of normal HTML elements as a convention to show that this is like a progressive enhanced version of this.

This means that it works without JavaScript or with JavaScript. So we have capital A anchor and capital F form. This allows us to do things like progressive enhance forms by just importing the capital F form component. So it'll work with or without JavaScript. And obviously there're anchor tag here, which also works that way.

But I wanna focus mostly, today we're gonna focus more on data fetching patterns and asynchronicity rather than on mutation. And one thing you can see here that already even though there isn't the loading indicator, is when I click next for the page, I mean it's happening so faster, there's a delay there.

You can see that page three doesn't update right away this is because those transitions are baked right into the app. And although we're not using it in this example we could because our router is routing and that is basically like the pending state. So if you ever wanna show that something stale you just import is is routing and you can use that to indicate what state you are in in your app.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now