-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update Sanity-Vercel introduction (#21)
- Loading branch information
1 parent
fc5e35d
commit a4fd284
Showing
19 changed files
with
330 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,10 @@ | ||
### Deploying through Vercel | ||
|
||
Create an account in Vercel (https://vercel.com/), it's free! | ||
|
||
Your project will be hosted by vercel and we will use the vercel CLI to deploy. | ||
|
||
Deploying your solution using the vercel CLI | ||
`vercel deploy` | ||
Deploy your solution using the vercel CLI | ||
`vercel deploy` | ||
|
||
Make sure that the url you get from vercel is accessible |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,17 @@ | ||
### Create a default page using a layout component with columns and a header component | ||
|
||
* In the `src`folder, create a new folder called `components` | ||
* Remove the content of the default page we got from vercel | ||
* Update the layout of the file | ||
* Add the following components | ||
* Add a header-component | ||
* Add a column-component | ||
* Add some dummy content that is displayed in the different components | ||
* Use [tailwind](tailwind.md) and typescript | ||
|
||
The page should look something like this: | ||
![image](https://github.com/emgdev/breakAway/assets/13402342/3d0f5067-e837-4dbf-ac62-e8d83264e099) | ||
|
||
Use regular React components for this, we don't use the app/ directory yet in prod | ||
|
||
[Deploy!](deploy.md) | ||
[Deploy the app to vercel!](deploy.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,48 @@ | ||
### Move the site listing to the url /sites | ||
Read about routing https://nextjs.org/docs/routing/introduction | ||
On the first page, add a link to the sites page | ||
## Create your first route | ||
|
||
[Deploy!](deploy.md) | ||
We want to move the listing of the sites to it's own page. We're also gonna create a new page for displaying a specific site. | ||
|
||
Read more about routing https://nextjs.org/docs/routing/introduction (specifically the Dynamic routing) | ||
|
||
### Setup | ||
* Create a new folder in the pages folder, and name it `sites` | ||
* In the new folder, create a new typescript file, name it `index.tsx` | ||
* This corresponds to the `/sites` route, and will be used to render the list of sites | ||
* In the new folder, create a new typescript file, name it `[slug].tsx` | ||
* This corresponds to `/sites/[site-slug]`, and will be used to display details of a specific site. | ||
|
||
_**Note:**_ The sites folder we created means we have now created a route called sites. The bracket filenaming means that our page can allow a parameter. | ||
|
||
### Home page | ||
Remove the list of the sites, and instead add a link to the sites index page. | ||
|
||
### Sites Index page | ||
Should display the list of sites, and link to the specific site pages. | ||
|
||
Read more about linking in a nextjs app here: https://nextjs.org/docs/pages/building-your-application/routing/linking-and-navigating | ||
|
||
### Move business logic away from page-components | ||
* Create a new folder on the same level as the pages folder, call it `handlers` | ||
* In this new folder, create a file called `SiteStaticDataHandler.ts` (see below for an example). Note that this is not a react file, it's not used for rendering, only for fetching data needed in our component. | ||
* Create a static method for fetching the sites in the component. | ||
* Use this handler in the sites index page and the site page to fetch the data from sanity. | ||
|
||
### Site page | ||
Fetch the site from sanity, based on the site slug. | ||
* If we can't match to a site, return 404 | ||
* If we find a site, fetch the properties from sanity. Send the slogan and color to the header component. (Should display the slogan using the site color as background.) | ||
|
||
### Deploy | ||
* [Deploy in vercel!](deploy.md) | ||
|
||
---- | ||
|
||
**Example of the `SiteStaticDataHandler`** | ||
``` | ||
# file: SiteStaticDataHandler.ts | ||
export class SiteStaticDataHandler { | ||
static async GetSites() | ||
static async GetSite(slug: string) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,33 @@ | ||
### Add a order button to the product page | ||
Add a button that will allow the user to add an email and then send the order to the backend. Create a new order in sanity. If there already exist a customer with the specific email then add that customer to sanity. If no customers exist then create one. | ||
## Creating an order for a product | ||
|
||
[Deploy!](deploy.md) | ||
In the pages folder, there should be a folder called `api` (if not, create the folder), with a sample file. The sample file exports a handler that returns a 200 with a payload. | ||
|
||
Since the api folder is created within the pages folder, the api folder automatically becomes a reachable route in our application. | ||
|
||
### Create a new api-endpoint. | ||
* Create file call it `order.ts` | ||
* Export another handler from that file. | ||
|
||
**The `api/order` handler** | ||
|
||
The handler should accept the payload needed for creating/updating a customer and creating an order. | ||
* Is there an existing customer with the email in the payload | ||
* Update the customer based on the payload data | ||
* Create an order and link it to the customer | ||
* If there's not an existing customer | ||
* Create a new customer | ||
* Create an order and link it to the new customer | ||
|
||
### Update the UI | ||
**The `products/{id}` page** | ||
* Update the product page, add the necessary input fields for creating/updating a customer and creating an order. | ||
* You will have to check the data model in sanity to discover which type of data is needed. | ||
* Add an "order button", that creates an order using the handler described above. | ||
* Make sure the UI updates after the order has been placed to notify the user. | ||
|
||
**Nice to have**: Add validation in the UI and in the API endpoint. | ||
|
||
_Note_: We can specify in the sanity document which properties should be required, and that's applied in the sanity UI. But when we use the client (or http endpoint) to post, that required field validation is not applied, i.e. we can post incomplete data if we are not careful. | ||
|
||
### Last step | ||
[Deploy to vercel!](deploy.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,10 @@ | ||
### Add the /products/{id} route that list the details about a specific product | ||
Grab the detail about the product from sanity and output them on the page | ||
## Adding the products to our app | ||
|
||
[Deploy!](deploy.md) | ||
* On the site page add a listing of the products connected to that site. | ||
* The items in the products list should point to the url /products/{id} | ||
* Add the /products/{id} route that list the details about a specific product | ||
* Grab the detail about the product from sanity and output them on the page | ||
|
||
Read more about linking in a nextjs app here: https://nextjs.org/docs/pages/building-your-application/routing/linking-and-navigating | ||
|
||
[Deploy to vercel!](deploy.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,31 @@ | ||
### Install the sanity client package and setup a connection to sanity using a .env file | ||
https://nextjs.org/docs/basic-features/environment-variables | ||
## We are connecting our vercel app to our sanity database | ||
|
||
### Part 1: | ||
|
||
**Preparation** | ||
* Install the [sanity client](https://www.npmjs.com/package/@sanity/client) by running `npm install @sanity/client` in the vercel/nextjs app. | ||
* We can now read data from sanity, see the client documentation for a basic sample. | ||
* To be able to access your sanity database, you will need to find the project id, which can be found in the Sanity Studio management ui. | ||
* We also need the name of the dataset, which also can be found in the management ui (if you've followed the previous steps, the name of the dataset will be `production`) | ||
|
||
**Excercise** | ||
* The goal is to display the names for the list of sites in sanity in one of the `Column` components. | ||
* Note that to use an async call to load data in react, you can use the `useEffect` hook. See: https://react.dev/reference/react/useEffect | ||
* Read up about the hook, and make sure you understand how it works | ||
* [Deploy the app to vercel!](deploy.md) | ||
|
||
_Hint:_ If you get a CORS error, you might need to add the url to your nextjs app in the list of allowed CORS-origins in the Sanity Studio management ui (found under the API-section) | ||
|
||
### Part 2: | ||
|
||
We want to avoid having secret information hardcoded in the files, and instead move it to the environment variables. | ||
|
||
You can read more about using environment variables in nextjs here: https://nextjs.org/docs/basic-features/environment-variables | ||
|
||
* In the top level folder of your nextjs application, add a file called `.env.local` | ||
* Add the project id, dataset and api version to the file. Note that the names needs to be prefixed with `NEXT_PUBLIC_` to assure that we can access them client side (see: [docs](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#exposing-environment-variables-to-the-browser)) | ||
* Update the code for your sanity client to use the new environment variables instead | ||
* Assure it's still working | ||
* [Deploy the app to vercel!](deploy.md) | ||
* Note that we need to add the environment variables in vercel as well to be able to deploy our app now | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,13 @@ | ||
### Take a minute to read through the concepts of `getServerSideProps` | ||
https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props | ||
and | ||
https://nextjs.org/docs/basic-features/pages#pre-rendering | ||
## Loading the content server side (`getServerSideProps`) | ||
|
||
### Write a query using `getServerSideProps` that fetch all the sites from Sanity | ||
Write a groq query that fetch all sites from Sanity and return those to the first page. Use the layout to show the sites and list all of the sites on the page. | ||
In the last excersise, we loaded the content of the page client side, now we're going to change it so that we load the page server side instead. | ||
|
||
[Deploy!](deploy.md) | ||
Look into the [documentation](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props) for `getServerSideProps`. | ||
|
||
**Excersise** | ||
* Move the rendering of the sites from client side to the server side. | ||
* [Deploy the app to vercel!](deploy.md) | ||
|
||
_Note:_ Now that we are using our environment variables server side instead, we can update them so that they are not accessed client side anymore (this is in general preferable). See the documentation: https://nextjs.org/docs/basic-features/environment-variables | ||
|
||
_Note 2:_ For these simpler examples we can use the `InferGetServerSidePropsType<typeof getServerSideProps>`, but for more complex scenarios we should aim to use a dedicated interface for the page components. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,28 @@ | ||
### Convert the function from `getServerSideProps` to `getStaticProps` | ||
|
||
For a nextjs application we can choose between static rendering, server side rendering or client side rendering. | ||
|
||
The difference between static rendering and server side rendering is that static rendered content will be rendererd at build time. The rendered content will then be cached for a specified time. | ||
|
||
Using static rendering improves the performance since everything is ready to be served to the user, but it does increase the build time. | ||
|
||
**To implement static rendering:** | ||
* Start with renaming the getServerSideProps to getStaticProps. | ||
* In your dynamic route (for the sites), add a method called `getStaticPaths` (https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths) | ||
* For this simple example, it just needs to return | ||
``` | ||
return { | ||
paths: [], | ||
fallback: 'blocking', | ||
}; | ||
``` | ||
* Update the default `getStaticPaths` to make sure it renders the pages for all the sites (update the paths parameter) | ||
|
||
_Note:_ | ||
* The paths parameter tells nextjs and vercel which paths to render at build time. If we leave it empty as above, no paths will be rendererd at build. | ||
* Fallback blocking means that if there's no page cached, the page will be server side rendered, and then cached. | ||
* In a real application, we would add the getStaticPaths per [dynamic route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes). | ||
|
||
Take some time to read about static rendering at https://nextjs.org/docs/basic-features/data-fetching/get-static-props | ||
|
||
[Deploy!](deploy.md) | ||
[Deploy!](deploy.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,38 @@ | ||
### Create a NextJS project: npx create-next-app@latest | ||
### Create a NextJS project: | ||
Create a new folder for the "web" project next to the "studio" folder on disk for the project | ||
|
||
In the newly created folder, run the following command `npx create-next-app@latest` | ||
|
||
This will start a interactive setup for your NextJS project. Use the following setup | ||
|
||
``` | ||
Your project name | ||
Ok to proceed? (y) | ||
[Select] y | ||
√ What is your project named? | ||
[Type] breakaway | ||
✔ Would you like to use TypeScript with this project? | ||
√ Would you like to use TypeScript with this project? | ||
[Select] Yes | ||
√ Would you like to use ESLint with this project? | ||
[Select] Yes | ||
√ Would you like to use Tailwind CSS with this project? | ||
[Select] Yes | ||
√ Would you like to use `src/` directory with this project? | ||
[Select] Yes | ||
√ Use App Router (recommended)? | ||
[Select] No | ||
√ Would you like to customize the default import alias? | ||
[Select] No | ||
``` | ||
|
||
_Note:_ We are not using the App Router in production, so if you end up with an `src/app` folder when you are done, you have done something wrong. What you should have is a folder called `pages` with an index file. | ||
|
||
### Start the nextjs site locally | ||
Start the solution by running `npm run dev`. A webpage running on localhost should be opened automatically. | ||
A new folder has been created for your project, move into it, and start the solution by running `npm run dev`. | ||
A webpage running on localhost should be opened automatically. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
### Observe that there is a missing `address` field for customers entities. Add the missing field in the schema | ||
Read through the article https://www.sanity.io/docs/schemas-and-forms to understand the basics about schemas. | ||
Deploy! | ||
### Observe that there is a missing `address` field for customers entities. | ||
|
||
* Read through the article https://www.sanity.io/docs/schemas-and-forms to understand the basics about schemas. | ||
* Add the missing `address` field in the schema | ||
* Deploy! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
### Add a logo to sanity studio | ||
Read on how the studio can be customized using studio components | ||
* Read on how the studio can be customized using studio components | ||
https://www.sanity.io/docs/studio-components | ||
Deploy! | ||
* Add a logo to the studio, logo url can be found [here](https://keystoneacademic-res.cloudinary.com/image/upload/v1630037941/element/16/168131_keg_left_small.png) | ||
* Deploy! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,15 @@ | ||
### Go to vision component and add a groq query | ||
Learn the basics about groq queries here https://www.sanity.io/docs/groq | ||
### Go to the vision component in sanity studio and add a groq query | ||
Learn the basics about groq queries here https://www.sanity.io/docs/groq | ||
|
||
Here are some suggested queries you can try out: | ||
* Select everything from all tables in the database, limit the query to the first 5 items | ||
* Select everything from the first 5 orders | ||
* Select everything from the first 5 customers, sorted by `firstname` | ||
* Select `_id` and `email` from the first 5 customers, sorted by `firstname` | ||
* Select `_id`, `amount`, `product.name`, `product.price` from one order (add a filter on the `_id`). Here we will join in the product to the order | ||
* Try to write the join both using the "dereference operator", and using a sub query | ||
* Select everything from the products with a price above a threshold | ||
* Select a specific product and dereference the site property | ||
* Update the query above to use the params instead for the filtering | ||
|
||
_**Note:**_ `Ctrl` + `/` can be used to comment out multiple lines in the query UI |
Oops, something went wrong.