Creating Cards
The best way to understand what a card can do is to first get some hands-on experience making one!
You can think of a Card as a "mini app" that can be run in different places within an app, or shared between different apps. For example, someone might build a Card that fetches and displays user information from a GitHub profile. The information could be displayed on a standalone page, or as a small widget on another page. Every Card has its own templates, styling, JavaScript files, tests, and more.
In this section of the Guides, you will learn how to run the Card Builder on your own computer so that you can learn and explore.
The average Cardstack user never needs to look at a terminal or a code editor; they do their work using visual interactions in the browser. But for developers, there are some additional powerful tools available, which we refer to as "Dev Mode." Keep reading to learn more!
Watch and Learn
This tutorial below will take you through step-by-step, but here's a video if you prefer to watch instead:
Prerequisites
See The Quickstart for the list of prerequisites that you should have installed on your computer in order to follow this tutorial.
Running the builder app locally
First, we'll install the Cardstack repository:
git clone https://github.com/cardstack/cardstack.git
cd cardstack
yarn install
There are a lot of files in here! You just downloaded the Card Builder and many of its key dependencies. You will be doing your own work in just a small number of files, so don't worry about most of these.
Next, make sure you have Docker running. Then open up the cardhost
app files, and run this command
to create a temporary database for your local development work:
cd packages/cardhost
yarn start-prereqs
Now, you can run the app itself:
yarn start
This will spin up two local servers - the Hub, which is a back end server, and the Builder, which is the front end application that you could use to create cards in a visual way.
Visit this URL in the browser to see your app running: http://localhost:4200
If you are having trouble with any of these steps, read the "Troubleshooting Tips" at the end of this article or drop by our Discord chat, and we'll help you get going!
Try making a Card
Before we look at the code, let's use the visual tools of the Builder to create a Card. This will be helpful context when we get to "Dev Mode" later.
From the browser, click on the Profile icon in the left edge and choose "log in." This allows you to simulate being a logged-in user, and make changes to your own local data, without requiring a username and password. It is for testing purposes only.
Once you are logged in, in the left edge, click on the Catalog button (it looks like a grid) and choose a card to make a copy of.
Visit the "Edit" mode to fill in forms, or the "Schema" mode to drag and drop new fields in. Visit "Layout" and click the "Custom Theme" button to write some CSS.
Feel free to explore! You can't permanently break anything, and your data is all stored on your computer only.
Enable Dev Mode
Now that we know that your local server works, let's turn on Dev Mode. In Dev Mode, Cards are saved to your hard drive as files, and you can look at the data that they are made of.
Stop your server from the terminal with Control-C
.
Next, create a new git repository somewhere on your hard drive, outside of the cardstack
repository. This will be the directory for
your new cards. Use pwd
to print the full directory path. You'll need it in the next step.
mkdir my-cards
cd my-cards
git init
pwd
Now, back in cardhost
, start your local server and set DEV_DIR
to your own path:
DEV_DIR="your/path/goes/here" yarn start
Now, try creating another card in the builder. Drag at least one field into it, such as text or number. We'll need it later.
You will see your card show up in the DEV_DIR
you specified!
There will be a new directory that has your card's
randomly-generated id for the directory name.
Inside is card.json
and package.json
.
card.json
has all the information needed to create a card.
It will look something like this:
{
"data": {
"attributes": {
"csCreated": "2020-03-23T21:11:05.993Z",
"csFields": {
},
"csTitle": "my-new-card",
"csUpdated": "2020-03-23T21:11:05.993Z"
},
"relationships": {
"csAdoptsFrom": {
"data": {
"id": "https://base.cardstack.com/public/cards/base",
"type": "cards"
}
}
},
"type": "cards"
},
"included": [
{
"attributes": {
"csCreated": "2020-03-23T21:11:06.016Z",
"csDescription": "This represents cards of any type",
"csFeatures": {
"embedded-css": "embedded.css",
"isolated-css": "isolated.css"
},
"csFiles": {
"card.json": "{\n \"data\": {\n \"type\": \"cards\",\n \"attributes\": {\n \"csTitle\": \"Base Card\",\n \"csDescription\": \"This represents cards of any type\",\n \"csFeatures\": {\n \"isolated-css\": \"isolated.css\",\n \"embedded-css\": \"embedded.css\"\n }\n },\n \"relationships\": {\n }\n }\n}",
"embedded.css": "(omitted for the example)",
"isolated.css": "(omitted for the example)",
"package.json": "(omitted for the example)"
},
"csId": "base",
"csPeerDependencies": {
"@cardstack/hub": "*"
},
"csTitle": "Base Card",
"csUpdated": "2020-03-23T21:11:06.016Z"
},
"id": "https://base.cardstack.com/public/cards/base",
"meta": {
"cardDir": "/Users/jenweber/projects/cardstack/node_modules/@cardstack/base-card"
},
"relationships": {
},
"type": "cards"
}
]
}
Making changes using Dev Mode
Now that we have the Card JSON, we can make changes to it using the Card Builder or modifying the JSON itself, aka the "Card Document." In some cases, this is faster or more powerful than creating cards directly in the builder; it is a tool at your disposal as a Card Creator!
Try changing the csTitle
of the card you made earlier:
"csTitle": "My New Title Goes Here",
Save, and refresh the browser page showing the card. You should see your new title in the card's header. If you study the JSON carefully, you will find that you can add new fields, change CSS, and more.
Next, try adding a new field.
Under csFields
, copy one of the fields you created,
paste it just inside the csFields
block,
and give it a new dasherized name, such as dev-mode-field-name
.
Don't forget to add a comma to separate your records.
You will also need to add the new field name in the
isolated
fields list and the csFieldOrder
, like shown below:
"csFieldOrder": [
"field-1", "dev-mode-field-name"
],
"csFieldSets": {
"embedded": [
],
"isolated": [
"field-1", "dev-mode-field-name"
]
},
"csFields": {
"field-1": {
"attributes": {
"csFieldArity": "singular",
"csFields": {
}
},
"relationships": {
"csAdoptsFrom": {
"data": {
"id": "https://base.cardstack.com/public/cards/string-field",
"type": "cards"
}
}
}
},
"dev-mode-field-name": {
"attributes": {
"csFieldArity": "singular",
"csFields": {
}
},
"relationships": {
"csAdoptsFrom": {
"data": {
"id": "https://base.cardstack.com/public/cards/string-field",
"type": "cards"
}
}
}
}
},
csFieldOrder
determines the order of the fields on the page.
isolated
is a list of the fields that should be included when the card is show in isolated (full page) mode, as opposed to what is shown in the embedded
(thumbnail size).
Saving data long-term
In this tutorial, we covered saving data to a local git repository. But what about saving it long-term? The Card Builder is designed to also save data to a private git repository hosted on GitHub. You can use this repository for deployed apps as well as local development. Stay tuned for more tutorials to help you get this set up!
Troubleshooting tips
Having trouble? Not sure where to look? These notes might help you out as you create Cards, add sample data records, and try to display them.
- Make sure you are running Node version 12 or later. Try
node -v
in the terminal - Is Docker running? Try
docker ps
. If it says "Cannot connect," launch the Docker app, wait until it is finished loading, and try again. - To see the data available in the local Cardstack Hub database, you can use postgres and SQL commands. In the terminal, run
docker exec -it cardstack-pg psql -U postgres pgsearch_cardboard_development
. This will open up a postgres shell. Many columns in tables are quite wide, so try selecting only from specific columns likeid
. Thedocuments
table is where Card data goes, so a sample query could beSELECT id FROM documents;
- Did you get the latest commits from the
master
branch of the Cardstack repository, and now things don't work? You might have some build artifacts lying around. Commit any work you want to keep, then delete thepackages
andcards
directories. Clear out yournode_modules
throughout the repository withnpx lerna clean
. Rungit reset --hard HEAD
to discard all uncommitted changes (i.e. get a clean slate), thenyarn install
. Stop your local database withyarn stop-prereqs
. Finally, follow the tutorial steps above, beginning withyarn install
to start the database and the app again. - Did you update the version of the
cardstack
repository that you are using? There might be orphaned JavaScript files lying around. Delete the contents ofcardstack/packages
and then discard the changes andyarn install
to get back to a fresh set of modules. - Visit our Discord chat for help
Starting over
Sometimes, you just need a clean environment for debugging if something is not working how you expect.
Follow these steps to get back to square one.
Please note that some of these commands are destructive to any uncommitted work, so don't do them if you are afraid of losing the changes you see during git status
.
From cardstack/packages/cardhost
:
Control-C
to stop your local servers.
yarn stop-prereqs # stop the docker container, if one is running
From cardhost
:
npx lerna clean # wipes out node_modules at all levels in the directory
rm -rf packages cards # delete any lingering compiled/generated files
git reset --hard HEAD # put the packages directory back to its original state in git
yarn install
Learn more
Are you ready to dig into how cards work? Keep reading the articles within the guides to level up.
Cards are a lot more than just components. See Cards at Rest, Cards in Motion and Building the Card Catalog to learn more about what makes them different from traditional web apps.
You can also watch the Card Folio community demo and read Community Q&A to get the big picture for how Cards compose together.