Precious Luke Open source crusader. I love building stuff with great technology.

Build a full-stack CRUD app with SolidJS

7 min read 2102 107

Build Full-Stack CRUD SolidJS App

We could begin a conversation about SolidJS by saying it is better than React, but there’s no need to make that comparison. SolidJS is just one of many frontend frameworks designed for creating fast, data-driven stuff on the web. So, why are we highlighting this new kid on the block?

Well, for one thing, we can’t overlook that SolidJS does not use a virtual DOM. Yes, you heard that right! Instead of using a virtual DOM, SolidJS memorizes the entire DOM from the first run of the application, then when there is an update, it goes ahead and updates that section. This feature makes the framework very fast and performant.

In this article, we’ll walk through how to build a simple CRUD application to demonstrate the effectiveness of SolidJS.

Jump ahead:

Prerequisites

To follow along with this tutorial, you should have the following:

  • Working knowledge of HTML, CSS, and JavaScript
  • Node.js and a package manager (like npm) installed on your machine
  • A code editor; we’ll use VS Code in this tutorial
  • Experience with additional frontend frameworks is helpful, but not required

Building the SolidJS frontend

To build our Solid application, we’ll use the Solid JD App library. We’ll set up the project, and then create and render the SolidJS components.

Installing the Solid JD App Library

To get started, run the following command on your terminal:

npm create jd-app@latest

You’ll be prompted to type y (for yes) to proceed, and then you‘ll be asked to provide a name for the app. Next, you’ll be asked if you will be using Vercel to deploy your project. This is a matter of preference. Where you decide to deploy or host your project is entirely up to you; you can even choose none as an option.

The library we’re using also comes with additional optional add-ons (AuthJS, Prisma, tRPC, pRPC, TailwindCSS, AuthJS, and Upstash Ratelimit). You can decide to select the ones you want or ignore them. For this tutorial, we will deploy to Vercel via the dashboard, and we will not use any of the optional add-ons:

Solid JD App Dashboard

Once your selections are made, click Enter. This will immediately install everything you need including the node_modules folder which has other packages that SolidJS depends on, as well as any that you selected during installation.

Setting up the project

For this tutorial, we’ll build a simple blog app. Move to the root directory, where the application is hosted, and run the following command:

npm run dev

This will start the application on port 3000; you will see it here http://localhost:3000.

Your codebase will look like this; note the use of TypeScript:

SolidJS Codebase Using TypeScript

Here’s what you’ll see in the browser:

Creating Solid JD App Browser

Next, clear the existing code in the src/route/index.tsx file and paste in the following:

import  "../assets/css/style.css";
import { type VoidComponent } from "solid-js";
import { A } from "solid-start";
import Blog from '../components/Blog'
const Home: VoidComponent = () => {
  return (
    <main>
       <div class="container">
          <div class="row g-4">
            <div class="col-lg-8">
              <div class="bg-mode p-4">
                <h1 class="h4 mb-4">Latest blogs</h1>

                </div>
            </div>

          </div>
        </div>
    </main>
  );
};
export default Home;

Creating the SolidJS components

Components are one of the best things about frontend frameworks, although the concept of components is not new. Components are simply a group of one or more HTML elements, but they make it easier for us to manage and reuse elements dynamically.

To start making components, create a folder in the src folder called components; this is where we’ll put any reusable elements and files. Inside the components folder, create a file called Blog.jsx and paste in the following code:

import solidimage from '../assets/images/solid.jpg'
function Blog() {
  return (
    <>
      <div class="card bg-transparent border-0">
        <div class="row g-3">
          <div class="col-4">
            <img class="rounded" src={solidimage} alt="" />
          </div>
          <div class="col-8">
            <a
              href="#"
              class="badge bg-danger bg-opacity-10 text-danger mb-2 fw-bold"
            >
             Tech
            </a>
            <h5>
              <a
                href="blog-details.html"
                class="btn-link stretched-link text-reset fw-bold"
              >
                What is Solidjs? 
              </a>
            </h5>
            <div class="d-none d-sm-inline-block">
              <p class="mb-2">
              SolidJS is an exciting framework for web development that has been gaining traction in recent years. It has been created by Misko Hevery, the creator of Angular. 
.
              </p>
              <a class="small text-secondary" href="#!">
                {" "}
                <i class="bi bi-calendar-date pe-1"></i> Jan 22, 2022
              </a>
            </div>
          </div>
        </div>
      </div>
      <hr class="my-4" />
    </>
  );
}
export default Blog;

You’ll also need to download an image and create the subfolder’s assets/images file inside the src folder.

Next, create a style.css file in the assets/css subfolders and add this code. The CSS in this code is Bootstrap.

Rendering the SolidJS component

You might encounter a problem, as I did, rendering the SolidJS component. If so, the simplest solution is to add the following in the tsconfig.json file that is located at the root of your project:

"noImplicitAny": false

We’re going to render the SolidJS component inside the index.tsx file in the src/route folder, like so:

import "../assets/css/style.css";
import { type VoidComponent } from "solid-js";
import { A } from "solid-start";
import Blog from '../components/Blog'
const Home: VoidComponent = () => {
  return (
    <main>
      <div class="container">
        <div class="row g-4">
          <div class="col-lg-8">
            <div class="bg-mode p-4">
              <h1 class="h4 mb-4">Latest blogs</h1>
              <Blog />
              <Blog/>
              <Blog/>
            </div>
          </div>
        </div>
      </div>
    </main>
  );
};
export default Home;

The only difference is that, on line 4, we imported the Blog component three times. Here’s what we now see in the web browser:

SolidJS Component Browser

Creating the dynamic rendering on the backend

What we just created in the prior section is static data. But, in the real world, data will be coming in from some sort of backend or API. So, let’s make things dynamic!

First, we’ll need to have some sort of endpoint. For this tutorial, we’ll use the following endpoint, https://crudcrud.com/api/6a1613c7646f4a908158592cfdb448aa/blog, which has a list of blogs:

CRUD Endpoint Blog List

To render the data coming from the API in the Blog component dynamically, update your Blog.jsx file, like so:

import { For, createResource } from "solid-js";
import solidimage from "../assets/images/solid.jpg";
const getBlogs = async () => {
  const response = await fetch(
    "https://crudcrud.com/api/6a1613c7646f4a908158592cfdb448aa/blog"
  );
  return response.json();
};
function Blog() {
  const [blog] = createResource(getBlogs);
  return (
    <Show when={blog()}>
      <For each={blog()}>
        {(eachblog) => (
          <>
            <div class="card bg-transparent border-0">
              <div class="row g-3">
                <div class="col-4">
                  <img class="rounded" src={solidimage} alt="" />
                </div>
                <div class="col-8">
                  <a
                    href="#"
                    class="badge bg-danger bg-opacity-10 text-danger mb-2 fw-bold"
                  >
                    {eachblog.tag}
                  </a>
                  <h5>
                    <a
                      href="blog-details.html"
                      class="btn-link stretched-link text-reset fw-bold"
                    >
                      {eachblog.title}
                    </a>
                  </h5>
                  <div class="d-none d-sm-inline-block">
                    <p class="mb-2">{eachblog.text}</p>
                    <a class="small text-secondary" href="#!">
                      {" "}
                      <i class="bi bi-calendar-date pe-1"></i> Jan 22, 2022
                    </a>
                  </div>
                </div>
              </div>
            </div>
            <hr class="my-4" />
          </>
        )}
      </For>
    </Show>
  );
}
export default Blog;

Here, we import the <For/> component that is coming from SolidJS. This component is used to loop through the content of the API (lines 13 and 49).

We also import a SolidJS CreateResource method. This is used to hold the content of the JSON response (line 10) that we get from the fetch response (see lines 3-8).

SolidJS also provides us with another component, <Show/>, that helps us render things conditionally. We use <Show/> to wrap the content of the entire Blog component.

The <Show/> component provides a when() method, which is where we actually define the conditions. We specify that the <Show/> component will only render when there is content when data or the variable exist (see line 12).

Here’s what the browser will look like:

SolidJS Dynamically Rendered Component

Setting up the routing

Routing refers to how we move from one path of a resource to another. Similar to other modern web technologies, SolidJS uses the Solid Router to manage how a client’s requests are handled and what handles them. The Solid Router is simple and straightforward.

At the time of writing, the Solid Router package is not installed by default. However, we used the Solid JD App Library to set up our project, and that library includes the Router.

To set up the routing, create a new component, BlogDetail.jsx, where the blog body will be shown. Then, paste in the following code:

import { useParams } from "@solidjs/router"
import { createResource } from "solid-js"
const getBlog = async (_id) => {
  const response = await fetch('https://crudcrud.com/api/64b773f6659a41b69d678369943f3c5f/blog/' + _id)
  return response.json()
}
export default function BlogDetail() {
  const params = useParams();
  const [blogdetail] = createResource(params._id, getBlog);
  console.log(blogdetail);
  return (
    <div class="my-7">
      <Show when={blogdetail()}>
        <div class="">
          <div class="">
            <h2 class="">{blogdetail.title}</h2>
            <h2>{blogdetail.body}</h2>

          </div>
        </div>tun
      </Show>
    </div>
  )
}

Looking at the API response, you’ll notice there is an _id field that is unique; this is what we will use to target each piece of content.



In this code, we import the useParams (line 1) which is used to target a particular param from the URL. Then, we fetch each blog post using their unique _id as a path parameter and returning it in a JSON (see lines 3-6).

Next, we export the BlogDetail (lines 13-24) and initiate useParams() in the params variable (line 8), which is used as a parameter in the CreateResource() method (line 9). Then, we return the title and body content of the blog (lines 11-23).

Now, we need to define this route in the src/route/index.tsx file. Update your code, like so:

import "../assets/css/style.css";
import { type VoidComponent } from "solid-js";
import { A, Router, Route, Routes } from "@solidjs/router";
import Blog from '../components/Blog';
import BlogDetail from '../components/BlogDetail';

const Home: VoidComponent = () => {
  return (
    <main>
      <div class="container">
        <div class="row g-4">
          <div class="col-lg-8">
            <div class="bg-mode p-4">
              <h1 class="h4 mb-4">Latest blogs</h1>
              <Blog />
            </div>
          </div>
        </div>
      </div>
      <Router>
      <Routes>
        <Route path='/blog/:_id' component={BlogDetail}/>       
      </Routes>
      </Router>
    </main>
  );
};
export default Home;

What changed here is that we imported the <Router/>, <Routes/>, <Route/> components from the solidjs/router package (line 3) and used them to collect data (lines 20-24). If you take a close look at line 22, you’ll see that we defined what happens when we try to access the blog post path parameter, /blog/_id. Since this has to be dynamic, we passed the component to return the BlogDetail.

Conclusion

In this article, we successfully demonstrated how to build a blog using SolidJS. You can extend these learnings to other types of applications. We looked at some SolidJS methods and components and investigated how they are used in a project.

One killer feature of SolidJS is that it memorizes the virtual DOM on the first load, subsequently, different parts will be updated as needed without affecting the entire DOM.

I hope you enjoyed this article. The full codebase of this project can be accessed on GitHub. You may also want to check out this deployment: https://solid-crud-ten.vercel.app/.

Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?

There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.

LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.

LogRocket Dashboard Free Trial Banner https://logrocket.com/signup/

LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

Build confidently — Start monitoring for free.

Precious Luke Open source crusader. I love building stuff with great technology.

Leave a Reply