The race for innovation between frontend frameworks has been evolving for fairly a while now. Whereas React has innovated with options like JSX, which makes expressing UI logic extra declarative, Svelte has launched compilation to scale back the dimensions of shopper bundles. However, SolidJS combines these concepts, together with the sensible use of composable primitives and observables.
Parallel to the innovation of those frameworks is the evolution of the meta-frameworks constructed on high of them, like Subsequent.js for React, SvelteKit for Svelte, and extra just lately, SolidStart for SolidJS. On this article, we’ll discover SolidStart, think about its options and use instances, and at last, construct a easy app. To observe alongside, you possibly can entry the full code for the tutorial on GitHub. Let’s get began!
Desk of contents
SolidStart options
SolidJS affords most of the options you’d anticipate from a meta-framework, together with file-based routing, API endpoints, and help for server-side, client-side, and static rendering.
SolidStart additionally comes geared up with some superb, distinctive options, like the flexibility to use kinds to set off server actions, just like RemixJS, in addition to the flexibility to simply outline RPC capabilities utilizing its $server
operate.
It’s essential to notice that on the time of writing, SolidStart remains to be in experimental standing, and lots of options could also be lacking or incomplete. It’s suggested to make use of SolidStart at your personal threat. With that mentioned, we are able to nonetheless use SolidStart to arrange a easy app.
Organising our SolidStart app
On this tutorial, we’ll construct a easy software that shops knowledge about enterprise journeys, together with mileage and site. To start, it’s best to have already got Node.js put in in your machine.
First, open up your code editor to an empty folder. Should you don’t have already got pnpm put in, run npm set up -g pnpm
. Then, run pnpm create stable
.
When prompted so as to add server-side rendering, choose sure. Choose no for TypeScript, then select a naked template. As soon as the app is generated, run pnpm set up
.
Folder construction
When utilizing SolidStart, the code you’ll work with will dwell within the /src
folder, which in itself accommodates some recordsdata and folders that you need to be accustomed to.
/elements
: Retailer all elements that aren’t pages within the/elements
folder/routes
: Retailer elements which can be pages in/routes
. A web page could be the default export of that fileroot/entry-client/entry-server
: Retailer recordsdata that deal with the appliance startup, which we don’t want to the touch
Create a /lib
folder, which you’ll use to create supporting recordsdata, for instance, plenty of our API implementation particulars, help capabilities, and extra.
Defining our enterprise journeys knowledge
As a substitute of utilizing a database, we’ll use an array to exhibit extra merely methods to work with our knowledge fashions. Should you’d relatively use MongoDB, you possibly can try this text.
Create a file referred to as src/lib/journeys.js
:
// The Journeys Array const journeys = [ { location: "Miami, FL", mileage: 80, }, { location: "Savannah, GA", mileage: 120, }, ]; // capabilities for working with journeys we are able to then convert into API routes or RPC calls export operate getTrips(){ return journeys } export operate createTrip(newTrip){ journeys.push(newTrip) return journeys } export operate updateTrip(id, updatedTrip){ journeys[id] = updatedTrip return journeys } export operate deleteTrip(id){ journeys.splice(id, 1) return journeys }
On this file, we’ve created a journey
array to carry our knowledge, in addition to capabilities for working with our array:
getTrips
: Returns the array of journeys, just likeSELECT * FROM desk
in SQLcreateTrip
: Takes in an object and creates a brand new journey by pushing it into an array, simulating aINSERT INTO desk VALUES (…)
question in a databaseupdateTrip
: Updates a visit within the array, just likeUPDATE desk WHERE situations SET updates
questiondeleteTrip
: Deletes a visit within the array, just likeDELETE FROM desk WHERE situations
question
These capabilities basically will simulate having a knowledge mannequin from a database ORM.
Now, we are able to make these capabilities usable to our software in two methods. For one, we are able to write API routes that use these capabilities. Alternately, in related elements, we are able to outline RPC calls utilizing these capabilities with the $server
operate. Remember the fact that RPC, a Distant Process Name, refers to when a operate that’s run on the server is named from a operate name on the shopper.
Utilizing API routes with SolidStart
Any route may be an API endpoint. The route file simply must export an async GET
/POST
/PUT
/DELETE
operate to deal with that kind of request for that route. If the route renders a web page by export defaulting a part, then you possibly can’t outline a further GET
for that route.
To indicate an instance of this, we’ll create a file referred to as src/routes/api/journeys/(journeys).js
. Discover that the file title has parenthesis round it. This can be a characteristic of SolidStart that lets you denote the principle file in a folder for a route. So, this file would deal with the /api/journeys
URL. Usually, we must title the file index.jsx
. After some time, having so many recordsdata with the identical title will get complicated.
Place the next code within the index.jsx
file:
// json operate for sending json responses import { json } from "solid-start"; import { getTrips, createTrip } from "~/lib/journeys"; export async operate GET(){ // return the array of journeys return json(getTrips()) } export async operate POST({request}){ // get the request physique const physique = await new Response(request.physique).json() // create new journey createTrip(physique) // return all journeys return json(getTrips()) }
Now, begin your server with npm run dev
, and it’s best to have the ability to use one thing like Postman or Insomnia to check the routes.
Make a GET
request to http://localhost:3000/api/journeys/
, and it’s best to get all of your journeys again:
Make a POST
request to http://localhost:3000/api/journeys/
with a JSON physique just like the one beneath, and it’s best to see the journey added:
{ "location": "Manchester,ct", "mileage": 1000 }
Superior, we now have working API endpoints, how simple was that!
Bringing within the journeys knowledge to the route
In SolidStart, we are able to pre-fetch knowledge for the route that’s accessible to the web page
route and all of the youngster elements.
We export routeData
, and its return worth turns into accessible to the web page and subcomponents through the useRouteData
Hook.
Let’s arrange our important web page src/routes/index.jsx
to create route knowledge as the results of an API name to our API Route:
import { createRouteData } from "solid-start"; // outline our route knowledge, server supplied knowledge to frontend export operate routeData() { return createRouteData(async () => { // fetch knowledge from api endpoint const response = await fetch("http://localhost:3000/api/journeys") const knowledge = await response.json() return knowledge }); } export default operate House() { return ( <important> </important> ); }
Discover that we used the createRouteData
operate. This operate works so much like React Question, the place we are able to wrap an asynchronous motion with the next advantages:
- Each time a route motion happens, the async operate will run once more, updating our knowledge
- The information may be given a novel title to help with caching if we’re utilizing the identical knowledge in a number of routes
We’ll see in our journey
part how we are able to use actions and route knowledge.
The Journeys
part
Now, we’ll create a file to place this all collectively in src/elements/Journeys.jsx
:
import { createRouteAction, useRouteData} from "solid-start"; import { createTrip } from "~/lib/journeys"; import server$ from "solid-start/server"; export default operate Journeys() { // deliver the route knowledge into our part const journeys = useRouteData(); // Outline an RPC name of what we need to run on the server const makeTrip = server$(async (journey) => createTrip(journey)) // outline a kind for creating a visit utilizing solid-states motion system const [_, { Form }] = createRouteAction(async (formData) => { // create the brand new journey object const journey = { location: formData.get("location"), mileage: formData.get("mileage") } // cross object RPC name to create new journey on server makeTrip(journey) }); return ( <div> <ul> {journeys()?.map((journey) => ( <li>{journey.location} - mileage: {journey.mileage}</li> ))} </ul> <Type> <enter kind="enter" title="location" placeholder="location"/> <enter kind="quantity" title="mileage" placeholder="mileage"/> <enter kind="submit"/> </Type> </div> ); }
On this part, we use many SolidStart options; for one, we use useRouteData
to get the routeData
outlined within the web page
part. server$
defines a operate that runs solely on the server. On this case, we would like the operate that creates Journeys
to run solely on the server because it wouldn’t work on the shopper.
Lastly, createRouteAction
creates a operate and the corresponding Type
part. The Type
part calls the operate that acts as an motion, triggering a refetch of routeData
.
Extra nice articles from LogRocket:
Displaying the Journeys
part
Edit your src/routes/index.jsx
as follows:
import { createRouteData } from "solid-start"; import Journeys from "~/elements/Journeys"; // outline our route knowledge, server supplied knowledge to frontend export operate routeData() { return createRouteData(async () => { // fetch knowledge from api endpoint const response = await fetch("http://localhost:3000/api/journeys") const knowledge = await response.json() return knowledge }); } export default operate House() { return ( <important> <Journeys/> </important> ); }
Utilizing the useRouteData
Hook, we export the routeData()
operate, which permits us to pre-fetch knowledge for use by the web page and it’s subcomponents.
The createRouteData
creates a useful resource that can refetch anytime an motion just like the one our kind triggers on submit
happens. Lastly, the <Journeys/>
part shows our journeys and kind.
Conclusion
Hopefully, you’ve gotten a way of simply how highly effective the SolidStart framework may be. Though it’s nonetheless experimental on the time of writing, SolidStart has a promising future. If you wish to see different variations of what you are able to do with SolidStart, try the next builds:
Are you including new JS libraries to enhance efficiency or construct new options? What in the event that they’re doing the other?
There’s little doubt that frontends are getting extra complicated. As you add new JavaScript libraries and different dependencies to your app, you’ll want extra visibility to make sure your customers don’t run into unknown points.
LogRocket is a frontend software monitoring answer that allows you to replay JavaScript errors as in the event that they occurred in your personal browser so you possibly can react to bugs extra successfully.
LogRocket works completely with any app, no matter framework, and has plugins to log further context from Redux, Vuex, and @ngrx/retailer. As a substitute of guessing why issues occur, you possibly can mixture and report on what state your software was in when a difficulty occurred. LogRocket additionally screens your app’s efficiency, reporting metrics like shopper CPU load, shopper reminiscence utilization, and extra.
Construct confidently — Begin monitoring without spending a dime.