Remix is a full stack web framework where data is rendered on the server for the client, adhering to web standards. Use Remix for a slick and resilient developer experience!
In this guide, we will walk through setting up a Remix project with Grafbase and then add a loader for fetching data.
To follow along, have these things installed:
npx create-remix@latest your-project-name
This is followed with prompts to install needed packages like create-remix
, and What type of app do you want to create?
, with this guide selecting Just the basics
.
The next few prompts ask where to deploy and typescript or javascript. This example uses Remix App Server
to deploy, and Typescript
, completing the installation with npm install
.
After choosing the default options and installing packages, it is ready for development!
Navigate to your new Remix project
cd your-project-name
View the default application by running npm run dev
and browsing localhost:3000
.
Create a GraphQL backend by initializing Grafbase with
npx grafbase@latest init
This generates a file grafbase/schema.graphql
in the project root folder.
Open the schema.graphql
file and replace the contents with
type Message @model {
author: String!
body: String!
}
Start Grafbase locally with a command and navigate to localhost:4000
npx grafbase@latest dev
Add data by running a mutation in the playground
mutation {
messageCreate(input: { author: "Dev", body: "GraphQL and Remix" }) {
message {
id
}
}
}
Verify the data is created with the return
{
"data": {
"messageCreate": {
"message": {
"id": "message_01GXXQCQKOT15RRX65DF10CD8H"
}
}
}
}
Now that we have data in our local instance, let's edit the app/routes/_index.tsx
page to fetch data with a Remix loader.
Replace the default function to return an unordered list, with the messages
to be defined in the next step.
export default function Index() {
return (
<main>
<h3>Grafbase Messages</h3>
<ul>
{messages.data.messageCollection?.edges?.map(
({ node }: { node: any }) => (
<li key={node.id}>
{node.author} - {node.body} - {node.createdAt}
</li>
),
)}
</ul>
</main>
)
}
Add the message and data types outside the function, along with the query for getting messages
type Message = {
id: string
author: string
body: string
createdAt: string
}
type Data = {
data: {
messageCollection: { edges: { node: Message }[] }
}
}
const GetAllMessagesQuery = /* GraphQL */ `
query GetAllMessages($first: Int!) {
messageCollection(first: $first) {
edges {
node {
id
author
body
createdAt
}
}
}
}
`
Add an import statement
import { useLoaderData } from '@remix-run/react'
Define the loader function and the fetch request (or other client request) to send the GraphQL query
export async function loader() {
const response = await fetch('localhost:4000/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: GetAllMessagesQuery,
variables: {
first: 100,
},
}),
})
return (await response.json()) as Data
}
And lastly, add your messages using Remix's useLoaderData
to your default function, to populate your page!
let messages = useLoaderData<typeof loader>()