Quickstart: Build & Deploy a Full-Stack App 

Hello, and welcome to Gadget!

In this quickstart we will build an app that will display a list of to-do tasks.

Here is what we'll learn:

  • Building a Model
  • Construct an Action (Interact with the CRUD API)
  • Setup your Frontend to display your Backend Data
  • Deploy your Application

Create a Gadget App 

  1. Start by creating a new Gadget app. Every new Gadget app includes a hosted Postgres database, a serverless Node backend, and a React frontend. You will use all of these to build your quickstart app!
Screenshot of Gadget's create a new app page

Build your Model 

  1. Click the + button in the Data Models section of the toolbar to create a new model. This is like adding a new table to a database

  2. Rename your model - "to-do"

GIF that shows how to add a model, and how to retask the model
  1. Click the + Add Field (F) button or use the hotkey F to create a new field. This is like adding a new column to your database table

  2. Rename your field to task

GIF that shows how to add a field, and how to retask the field
  1. When you add a new model, a CRUD (Create, Read, Update, Delete) GraphQL API for that model is automatically generated for you. Click the create action and click on the Test Action button to open the GraphQL playground with the createToDo GraphQL mutation pre-loaded
Screenshot of the API Reference link in the Gadget toolbar
  1. Add the following snippet to the Variables section in the playground
Input in Variables
json
{
"toDo": {
"task": "build a Gadget app"
}
}

  1. Click the run button OR use the Ctrl + Enter hotkey to run the GraphQL query - you should get a response with success: true and your created model Screenshot of the GraphQL playground with the to-do model's Create mutation and a successful Create operation response
  2. Return to Gadget
  3. Click on the Data button for to-do to see the record you have just added Screenshot of the to-do model's Data button in the Gadget toolbarScreenshot of the to-do model's Data page You have successfully built a new model, added a custom field to that model, and used Gadget's generated CRUD API to add a record to that model.

Construct an Action 

You can also add custom code that runs when your CRUD actions are triggered. To do this, you are going to add some custom code that prints to Gadget's logger each time a new to-do is created in your app.

  1. Go to the Model page for to-doScreenshot of the to-do model's Behavior button in the Gadget toolbar
  2. Click on the Create action in the actions panel
  3. Click + Add Code Snippet This code file runs as a Success effect, which means that the Run effects have already completed and your new record is already saved to the Gadget database by the time this code file is run. Success effects are great for sending data to external systems, like a payment system, or for sending notifications, such as email or SMS alerts Screenshot of the to-do model's Create action panel
  4. Paste the following snippet, which will print a message and the fields of your new to-do record to the Logger each time a to-do is created
JavaScript
1/**
2 * Effect code for Create on to-do
3 * @param { import("gadget-server").Createto-doActionContext } context - Everything for running this effect, like the api client, current record, params, etc
4 */
5module.exports = async ({ api, record, params, logger }) => {
6 logger.info({ record }, "task added!");
7};

  1. Go back to your API Playground and re-run the create mutation for a to-do
  2. Click on Logs near the top of the nav bar in Gadget to open the logger
  3. Toggle User events only on to see the message printed in the Logs Screenshot of the logger output If you go back to to-do data page, you will see a second record has been added as well. You have just added a custom code effect that runs each time you add a new record to to-do.

Update action permissions 

When you build your frontend, you are going to read to-do data from your database. You don't want to build an authentication and login system right now, so you need to permit unauthenticated requests permission to read to-do data. By default, new model records are not readable by unauthenticated users. You need to give your to-do model's read action permission to return data for unauthenticated requests.

  1. Click on Settings in the Gadget nav bar, and then Roles & Permissions
  2. Enable Unauthenticated permission for your to-do model's read action Screenshot of the Roles & Permissions page, with the to-do model's read action given unauthenticated access. An arrow highlights the checkbox that needs to be clicked. That's it for your app backend and database, now you can move on to your frontend.

Setup your Frontend 

A frontend template, found in the frontend folder, is provided for you when you create a new Gadget app. You're going to modify this template to display to-do tasks. Hot module reloading works with Gadget-hosted React frontends, so before you modify your template you can open your development environment app in your browser:

  1. Click on your app task in the top left corner and select Go to app and click on your app URL. Your frontend should open in a new browser tab Animated screenshot of user clicking on top left corner of their Gadget app, selecting the 'Go to app' option from the dropdown menu, and clicking on their development app URL
  2. Back in Gadget, open the frontend/App.jsx file that powers your development app A screenshot of the default frontend folder in a new Gadget project, containing the App.jsx that will be modified
  3. Gadget automatically generates a JavaScript API client as you build your backend app. You can use this client to make requests from your frontend to your Todo API.
frontend/App.jsx
jsx
// add a new import of the Gadget API client
import { api } from "./api";
  1. Gadget also provides some useful React tooling that helps you call your API, found in the @gadgetinc/react npm package that is already pre-installed upon creation of your Gadget app. In App.jsx import the use a useFindMany hook which will be utilized to read to-do data.
frontend/App.jsx
jsx
import { useFindMany } from "@gadgetinc/react";
  1. Now, you can use api and useFindMany together to read Todo records
frontend/App.jsx
jsx
const App = () => {
const [{ data: toDos, fetching: isFetching, error: e }] = useFindMany(api.toDo);
// other code included in the default App template
return (/* existing app template */);
}

The useFindMany hook provides a response object that contains data, fetching, and error fields. The data field contains your to-do model records. The fetching field is a boolean - when true it can be used to display a loading state. Finally, error can be used to handle any response errors.

  1. Use data, aliased as toDos, to display a list of to-dos in your frontend. You can also use fetching, aliased as isFetching, to display a loading message. Replace the contents of the return statement in App.jsx with the following snippet:
frontend/App.jsx
jsx
1return (
2 <main>
3 <h1>My to-dos</h1>
4 {isFetching ? (
5 <p>Loading...</p>
6 ) : (
7 <ul>
8 {toDos?.map((toDo) => (
9 <li>{toDo.task}</li>
10 ))}
11 </ul>
12 )}
13 </main>
14);
  1. Go back to your development app URL and you should now see a list of to-dos! Gadget frontends include hot module reloading (HMR), so your app should update as you write code. There is a timeout for the websocket that HMR uses - to restart it, simply refresh the tab for your development app.
Screenshot of the completed app frontend - a list of to-dos

Deploying to Production 

Deploying your app is as simple as one click.

  1. In the bottom right-hand corner of your application, click on the deploy button and confirm your changes.
Screenshot of deploying to-do app to production

Congrats! You just built and deployed a full stack app that allows you to store data of your to-do's, runs some custom code to print the to-do data to your logs, and displays to-do data in a React frontend.

Next steps 

Similar to the useFindMany hook used to read data, the @gadgetinc/react package also has a useAction hook that can be used to call a model's create, update, delete, or any custom actions. Try using useAction with the to-do model's create action to write data to your database!

If you want to walk through using useAction to write data to your Gadget database, and how to set up a Shopify connection in Gadget try the product tagger tutorial:

Automated product tagger
10 mins

Build a simple application that automatically tags products in a Shopify store based on description keywords. Learn about Shopify connections, Gadget's API, and how to write data back to Shopify.