docs: improved contentful documentation (#1891)
This commit is contained in:
@@ -1,318 +0,0 @@
|
||||
# Contentful
|
||||
|
||||
## Introduction
|
||||
|
||||
In this guide we will go over how to set up a modern e-commerce store using [Gatsby](https://gatsby.com) as a front end, [Contentful](https://contentful.com) as a CMS system and Medusa as a store engine. The resulting e-commerce store will be blazingly fast, highly extendable and will provide the necessary foundation to grow and evolve your e-commerce stack as your business expands to new markets and develops new software requirements.
|
||||
|
||||
## Overview
|
||||
|
||||
After following the steps outlines in this series you will have:
|
||||
|
||||
- A Medusa store engine capable of managing products, processing orders, handling orders and integrating with all the tools in your e-commerce stack.
|
||||
- A statically generated Gatsby storefront that is on brand and customizable from homepage to checkout flow.
|
||||
- A headless CMS system that can be modified and extended to create the best customer experience.
|
||||
|
||||
You will make use of `medusa-plugin-contentful` which is a plugin to your Medusa store engine that syncronizes products and product variants between your Medusa engine and your Contentful space. This allows you to perform content enrichment in Contentful while keeping your core master data in Medusa, for a truly headless commerce setup.
|
||||
|
||||
Other concepts that will be covered in this series include:
|
||||
|
||||
- Gatsby plugins and [File System Route API](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/)
|
||||
- [Contentful Migrations](https://www.contentful.com/developers/docs/tutorials/cli/scripting-migrations/)
|
||||
- Medusa payments, fulfillments and plugins
|
||||
|
||||
If you want to jump straight to the code for this series you can checkout:
|
||||
|
||||
- [`medusa-starter-contentful`](https://github.com/medusajs/medusa-starter-contentful)
|
||||
- [`medusa-contentful-storefront`](https://github.com/medusajs/medusa-contentful-storefront)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
:::note
|
||||
|
||||
For a full guide to how to set up your development environment for Medusa please see [the tutorial](../tutorial/set-up-your-development-environment/)
|
||||
|
||||
:::
|
||||
|
||||
In order to get you started with your Gatsby, Contentful, Medusa store you must complete a couple of installations:
|
||||
|
||||
- Install the Medusa CLI
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/medusa-cli -g
|
||||
```
|
||||
|
||||
- Install the Gatsby CLI
|
||||
|
||||
```bash npm2yarn
|
||||
npm install gatsby-cli -g
|
||||
```
|
||||
|
||||
- [Create a Contentful account](https://www.contentful.com/sign-up/)
|
||||
- [Install Redis](https://redis.io/topics/quickstart)
|
||||
|
||||
```bash
|
||||
brew install redis
|
||||
brew services start redis
|
||||
```
|
||||
|
||||
Medusa has support for SQLite and PostgreSQL and uses Redis for caching and queueing of asynchronous tasks. Redis is required for `medusa-plugin-contentful` to work correctly.
|
||||
|
||||
## Setting up your Medusa server
|
||||
|
||||
We will make use of `medusa new` to setup your local Medusa server.
|
||||
|
||||
```sh
|
||||
medusa new medusa-contentful-store https://github.com/medusajs/medusa-starter-contentful
|
||||
```
|
||||
|
||||
This command will setup a new directory at `medusa-contentful-store`, clone the `medusa-starter-contentful` into that directory and install the dependencies for the project.
|
||||
|
||||
### What's inside
|
||||
|
||||
You can now do `cd medusa-contentful-store` and open up your project in your text editor. Below is an overview of the directory structure and a walkthrough of what the different files do.
|
||||
|
||||
```
|
||||
medusa-contentful-store
|
||||
├── contentful-migrations
|
||||
| ├── hero.js
|
||||
| ├── index.js
|
||||
| ├── link.js
|
||||
| ├── navigation-item.js
|
||||
| ├── navigation-menu.js
|
||||
| ├── page.js
|
||||
| ├── product-variant.js
|
||||
| ├── product.js
|
||||
| ├── region.js
|
||||
| ├── tile-section.js
|
||||
| └── tile.js
|
||||
├── data
|
||||
| ├── contentful-seed.json
|
||||
| └── seed.json
|
||||
├── src
|
||||
| ├── api
|
||||
| ├── loaders
|
||||
| ├── services
|
||||
| └── subscribers
|
||||
├── .env
|
||||
├── medusa-config.js
|
||||
├── package.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
#### `package.json`
|
||||
|
||||
If you are familiar with Node you will probably notice that your Medusa store is simply a Node project. Looking inside the `package.json` file you will find that one of the packages that is installed in the project is the `@medusajs/medusa` package. This is the core Medusa package that comes prepacked with all the functionality necessary to do digital commerce - it is also this package that makes sure to register and use the plugins and custom functionality that are configured for your store.
|
||||
|
||||
#### `medusa-config.js`
|
||||
|
||||
Your plugins and store configuration is managed in the `medusa-config.js`, if you open up the file you will see that `medusa-plugin-contentful` is configured with options as shown below. Later we will be setting up your Contentful space so that we can add the necessary environment variables to your `.env` file.
|
||||
|
||||
```javascript
|
||||
// medusa-config.js
|
||||
|
||||
// Contentful Variables
|
||||
const CONTENTFUL_SPACE_ID = process.env.CONTENTFUL_SPACE_ID || "";
|
||||
const CONTENTFUL_ACCESS_TOKEN = process.env.CONTENTFUL_ACCESS_TOKEN || "";
|
||||
const CONTENTFUL_ENV = process.env.CONTENTFUL_ENV || "";
|
||||
|
||||
|
||||
const plugins = [
|
||||
...,
|
||||
{
|
||||
resolve: `medusa-plugin-contentful`,
|
||||
options: {
|
||||
space_id: CONTENTFUL_SPACE_ID,
|
||||
access_token: CONTENTFUL_ACCESS_TOKEN,
|
||||
environment: CONTENTFUL_ENV,
|
||||
},
|
||||
},
|
||||
...
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
redis_url: REDIS_URL,
|
||||
database_database: "./medusa-db.sql",
|
||||
database_type: "sqlite",
|
||||
store_cors: STORE_CORS,
|
||||
admin_cors: ADMIN_CORS,
|
||||
},
|
||||
plugins,
|
||||
};
|
||||
```
|
||||
|
||||
#### `/src`
|
||||
|
||||
In the `/src` directory there are 4 special subdirectories that are added for you already. These special directories can be used to add custom functionality to your store. Custom functionality can include custom endpoints (configured in `/api`), custom business logic (configured in `/services`), pub/sub-like subscriptions for asyncrhonous integration tasks (configured in `/subscribers`) and finally loader functions to be called when your Medusa server starts up (configured in `/loaders`). If you want to learn more about how to add custom functionality you can checkout [the tutorial](https://docs.medusajs.com/tutorials/adding-custom-functionality).
|
||||
|
||||
#### `/data`
|
||||
|
||||
We will be using two seed scripts to kickstart your development, namely:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run seed:contentful
|
||||
npm run seed
|
||||
```
|
||||
|
||||
Data for these seed scripts are contained in the `/data` directory.
|
||||
|
||||
When the seed scripts have been executed you will have a Contentful space that holds all the data for your website; this includes content for Pages, Navigtion Menu, etc.
|
||||
|
||||
#### `/contentful-migrations`
|
||||
|
||||
This directory contains scripts that create content types in your Contentful space. Contentful allows you to customize your content types with fields that can be used to hold all sorts of data, this makes it possible to create advanced data structures that will later be used to lay out your website. Writing migration scripts to evolve your content types is a really powerful tool as you can use it in CI/CD pipelines and makes your projects much more portable.
|
||||
|
||||
The migrations included in this project will create the following content types:
|
||||
|
||||
- **Page**: Represents a page on your website. Each page has a title and can take any number of "Content Modules". Content Modules can be either of the type Hero or Tile Section.
|
||||
- **Hero**: a component that can take a Title, CTA and a background image.
|
||||
- **Tile**: a component that can be added to a Tile Section and renders a Title, CTA and an Image.
|
||||
- **Tile Section**: a component that can hold a number of Tiles or Products. When used with a Product, the Tile Section will display the product thumbnail and it's title and will link to the product page.
|
||||
- **Link**: a component that can link to an external or internal path; or, alternatively, hold a reference to a Page or Product entry. If used with Page or Product, the link path will be infered from the referenced entry.
|
||||
- **Navigation Item**: an item to include in a Navigation Menu. Each navigation item has a title that can be displayed in a menu and a link that defines where the user will be navigated to when the item is clicked.
|
||||
- **Product**: represents a product as syncronized from Medusa. A product's variants will be copied over as well.
|
||||
- **Product Variant**: The variants of a product.
|
||||
- **Region**: Represents an available region in Medusa.
|
||||
|
||||
## Creating a Contentful space
|
||||
|
||||
To create a new Contentful space log in to your Contentful account. If you already have a Contentful account with a Space configured you can click your organization name in the top left corner to reveal an overview of your organization's spaces. At the bottom of the spaces list you should click "Add space".
|
||||
|
||||
**Select "Community space" and "Web app only"**
|
||||
In this guide we will be using a free space which gives you an incredibly strong foundation for creating on-brand customer experiences and advances shopping flows.
|
||||
|
||||

|
||||
|
||||
**Add a name and select "Empty space"**
|
||||
|
||||

|
||||
|
||||
Once your space is set up you can go to your space home. We will now get the credentials needed for `medusa-plugin-contentful` to work.
|
||||
|
||||
Open your `.env` file in your text editor you should see:
|
||||
|
||||
```shell
|
||||
# .env
|
||||
JWT_SECRET=something
|
||||
COOKIE_SECRET=something
|
||||
|
||||
STRIPE_API_KEY=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
|
||||
CONTENTFUL_SPACE_ID=
|
||||
CONTENTFUL_ACCESS_TOKEN=
|
||||
CONTENTFUL_ENV=
|
||||
```
|
||||
|
||||
Your `CONTENTFUL_SPACE_ID` can be found by going to your space home and checking your browser's URL bar. The space id is the alphanumeric string following `https://app.contentful.com/spaces/`. Copy this string and paste it into your `.env` file.
|
||||
|
||||
To get your `CONTENFUL_ACCESS_TOKEN` go to your space home and click **Settings** > **API keys**
|
||||
|
||||

|
||||
|
||||
Then click **Content management tokens** and click **Generate personal token**. After giving your token a name you can copy it to your `.env`
|
||||
|
||||

|
||||
|
||||
For `CONTENTFUL_ENVIRONMENT` add `master`.
|
||||
|
||||
You should now have a `.env` that looks like this:
|
||||
|
||||
```shell
|
||||
# .env
|
||||
JWT_SECRET=something
|
||||
COOKIE_SECRET=something
|
||||
|
||||
STRIPE_API_KEY=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
|
||||
CONTENTFUL_SPACE_ID=****
|
||||
CONTENTFUL_ACCESS_TOKEN=CFPAT-*******
|
||||
CONTENTFUL_ENV=master
|
||||
```
|
||||
|
||||
## Migrating and Seeding your Contentful space
|
||||
|
||||
Now that we have collected your credentials we are ready to migrate the Contentful space to add the content types we talked about earlier. To migrate the Contentful space open up your command line and `cd` into `medusa-contentful-store`.
|
||||
|
||||
You can now run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run migrate:contentful
|
||||
```
|
||||
|
||||
This script will run each of the migrations in the `contentful-migrations` directory. After it has completed navigate to your Contentful space and click "Content model" in the top navigation bar. You will see that the content types will be imported into your space. Feel free to familiarize yourself with the different types by clicking them and inspecting the different fields that they hold.
|
||||
|
||||

|
||||
|
||||
The next step is to seed the Contentful space with some data that can be used to display your ecommerce store's pages and navigation. To seed the database open up your command line and run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run seed:contentful
|
||||
```
|
||||
|
||||
In your Contentful space navigate to "Content" and you will be able to see the different entries in your space. You can filter the entries by type to, for example, only view Pages:
|
||||
|
||||

|
||||
|
||||
You will notice that there are not any Products in your store yet and this is because we haven't created any products in your Medusa store.
|
||||
|
||||
To do this open your command line and run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run seed
|
||||
npm run start
|
||||
```
|
||||
|
||||
This will seed your Medusa database, which will result in `medusa-plugin-contentful` synchronizing data to your Contentful space. Everytime you add or update a product the data will be copied into your Contentful space for further enrichment.
|
||||
|
||||
## Setting Featured Products
|
||||
|
||||
In Contentful navigate to "Content" and find the Page called "Home". We will now add some featured products to the home page.
|
||||
|
||||
- Click the "Home" entry and scroll down to the field called "Content modules"
|
||||

|
||||
|
||||
- Click the Content module named "Featured Products" and click "Add content" in the "Tiles" field
|
||||

|
||||
|
||||
- Click "Add existing content" as e will be adding the products that were copied over by Medusa
|
||||

|
||||
|
||||
- Select Medusa Waterbottle and Medusa Shirt and click "Insert 2 entries"
|
||||
|
||||
Make sure that everything is published by hitting publish in the sidebar on the right-hand side.
|
||||
|
||||
## Setting up your Gatsby storefront
|
||||
|
||||
Now that we have your Medusa server running and your Contentful space seeded with some starter data it is time to add a presentational layer that can be used by customers to browse and purchase the items in your store.
|
||||
|
||||
We have already created the storefront and you can install and use it by simply running:
|
||||
|
||||
```
|
||||
gatsby new medusa-contentful-storefront https://github.com/medusajs/medusa-contentful-storefront
|
||||
```
|
||||
|
||||
Once `gatsby new` is complete you should rename the `.env.template` file to `.env` and add a Content Delivery token. Your content delivery token is different from the personal access token you generated earlier, so make sure that you are using the correct token when you paste it into your `.env`.
|
||||
|
||||
To get your token go to **Settings** > **API Keys** > **Add API key**. Now click save and copy the token specified in the field "Content Delivery API - access token".
|
||||
|
||||
After you have copied the token and your space ID to your `.env`, you can start your Gatsby development server on port 8000 by running:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run start
|
||||
```
|
||||
|
||||
You can now go to https://localhost:8000 to check out your new Medusa store.
|
||||
|
||||

|
||||
|
||||
## Summary
|
||||
|
||||
Using three powerful tools we have now set up a modern headless ecommerce store on our local development machine. This setup can scale with your business's needs and evolve to fit create amazing commerce expereiences that are unique and on brand. The steps we took in this guide were really simple and fast: first we created a Medusa server using the Medusa CLI, we then configured a Contentful space by running migrations and seed scripts. We also installed a Gatsby front end for our Medusa store using the Gatsby CLI.
|
||||
|
||||
## What's next
|
||||
|
||||
In the next part we will dig deeper into how Contentful can be used to create pages, enrich your products and structure your content. We will also take a look at the files in your Gatsby storefront.
|
||||
|
||||
Stay tuned!
|
||||
314
docs/content/add-plugins/contentful/customize-contentful.md
Normal file
314
docs/content/add-plugins/contentful/customize-contentful.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Customize your Medusa and Contentful Integration
|
||||
|
||||
In this document, you’ll learn how to customize the Contentful integration with Medusa and how to customize the Gatsby storefront that is connected to Contentful.
|
||||
|
||||
## Overview
|
||||
|
||||
Part of what makes the integration between Medusa and Contentful powerful is that it’s completely customizable.
|
||||
|
||||
On the server, you can create Contentful migrations that allow you to add or edit Content Types in Contentful. Although this can be done through Contentful’s interface, this solution allows you to create a reusable codebase for your store that is independent of a specific Contentful Space.
|
||||
|
||||
On your storefront, you can add any necessary components that can render the Content Types you create.
|
||||
|
||||
As an example to explain this process, in this documentation, you’ll create a migration that creates a Rich Text content model in Contentful and edits the Page and Product content models to allow using Rich Text content as a tile in pages and products. Then, you’ll modify the Gatsby storefront to render the Rich Text content model.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
It’s assumed you already have set up a Medusa server integrated with Contentful and have a Gatsby storefront integrated with Contentful. If not, [please follow this documentation first](index.md).
|
||||
|
||||
## Create a Contentful Migration
|
||||
|
||||
The Contentful migrations are located in the `contentful-migrations` directory in the Medusa Contentful server starter. So, if you want to create your own Contentful migrations, you can create them under that directory.
|
||||
|
||||
Here’s an example of a migration created in a new file `contentful-migrations/rich-text.js`:
|
||||
|
||||
```jsx
|
||||
#! /usr/bin/env node
|
||||
|
||||
require("dotenv").config();
|
||||
|
||||
const { runMigration } = require("contentful-migration");
|
||||
|
||||
const options = {
|
||||
spaceId: process.env.CONTENTFUL_SPACE_ID,
|
||||
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
|
||||
environment: process.env.CONTENTFUL_ENVIRONMENT,
|
||||
yes: true,
|
||||
};
|
||||
|
||||
const migration = async () => {
|
||||
await runMigration({
|
||||
...options,
|
||||
migrationFunction: function (migration, context) {
|
||||
|
||||
//create Rich Text content model
|
||||
const richText = migration
|
||||
.createContentType("richText")
|
||||
.name("Rich Text")
|
||||
.displayField("title");
|
||||
|
||||
richText.createField("title").name("Title (Internal)").type("Symbol");
|
||||
richText.createField("body").name("Body").type("RichText");
|
||||
|
||||
//edit Page content model
|
||||
const page = migration.editContentType("page")
|
||||
|
||||
page.editField("contentModules").items({
|
||||
type: "Link",
|
||||
linkType: "Entry",
|
||||
validations: [
|
||||
{
|
||||
linkContentType: ["hero", "tileSection", "richText"],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
//edit Product content model
|
||||
const product = migration.editContentType("product")
|
||||
|
||||
product
|
||||
.createField("contentModules")
|
||||
.name("Content Modules")
|
||||
.type("Array")
|
||||
.items({
|
||||
type: "Link",
|
||||
linkType: "Entry",
|
||||
validations: [
|
||||
{
|
||||
linkContentType: ["richText"],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
migration();
|
||||
```
|
||||
|
||||
This example creates a new content model Rich Text that has two fields: title and body. It also edits the Page content model to allow using Rich Text content models on the page.
|
||||
|
||||
In addition, it edits the Product content model by adding a new field `contentModules`. This field accepts an array of sections that can be of type Rich Text. This allows you to display rich details on a product page.
|
||||
|
||||
You can also add other types of content models the `contentModules` should accept. For example, to accept `tileSection` add it to the `linkContentType` option:
|
||||
|
||||
```jsx
|
||||
linkContentType: ["tileSection", "richText"],
|
||||
```
|
||||
|
||||
### Run a Contentful Migration
|
||||
|
||||
To run a Contentful Migration that you create you can use the following command:
|
||||
|
||||
```bash
|
||||
node <file_path>
|
||||
```
|
||||
|
||||
Where `<file_path>` is the path of the file you created.
|
||||
|
||||
To run the Contentful migration in the previous example, you can use the following command:
|
||||
|
||||
```bash
|
||||
node contentful-migrations/rich-text.js
|
||||
```
|
||||
|
||||
This runs the Contentful migration in that file and makes the necessary changes in your Contentful Space.
|
||||
|
||||
### Test if Contentful Migration Worked
|
||||
|
||||
To check if the above migration worked, in your Contentful Space dashboard go to Content Models from the navigation bar. You should see the new content model Rich Text.
|
||||
|
||||

|
||||
|
||||
The above migration also allows you to add Rich Text content to pages. To test this out, go to Content from the navigation bar and choose Page in the select field next to the search bar. This shows the available pages in your Contentful Space.
|
||||
|
||||

|
||||
|
||||
Choose one of the pages. For example, the About page. Then, scroll down to the Add content button. If you click on it, you should be able to choose Rich Text under New Content.
|
||||
|
||||

|
||||
|
||||
Click on Rich Text and a new form will open to create new Rich Text content. It has the same fields that you defined in the migration file.
|
||||
|
||||

|
||||
|
||||
After adding the content you want, click on the Publish button on the right then go back to the About page editor.
|
||||
|
||||

|
||||
|
||||
Similarly, in the About page editor, click on the Publish Changes button on the right to view these changes later in the storefront.
|
||||
|
||||

|
||||
|
||||
Similarly, you can add Rich Text content to any product page.
|
||||
|
||||

|
||||
|
||||
## Render New Content Models in the Storefront
|
||||
|
||||
After creating a new content model in your Contentful Space, you must add the necessary component to render it in your Gatsby storefront.
|
||||
|
||||
### Create Component
|
||||
|
||||
To render the Rich Text content you created in the previous example, create the file `src/components/rich-text/rich-text.js` with the following content:
|
||||
|
||||
```jsx
|
||||
import React from "react"
|
||||
import { renderRichText } from "gatsby-source-contentful/rich-text"
|
||||
|
||||
const RichText = ({ data }) => {
|
||||
return (
|
||||
<div style={{
|
||||
maxWidth: '870px',
|
||||
margin: '0 auto',
|
||||
paddingTop: '20px',
|
||||
paddingBottom: '20px'
|
||||
}}>
|
||||
{data.body ? renderRichText(data.body) : ""}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RichText
|
||||
```
|
||||
|
||||
This creates the component `RichText` responsible for rendering the Rich Text content model. Notice that the fields of the content model are available under the `data` prop variable.
|
||||
|
||||
### Render Component in a Page
|
||||
|
||||
Since the Rich Text model can be added to any page, you must edit `src/pages/{ContentfulPage.slug}.js` to show it.
|
||||
|
||||
In `src/pages/{ContentfulPage.slug}.js`, import the `RichText` component at the top of the file:
|
||||
|
||||
```jsx
|
||||
import RichText from "../components/rich-text/rich-text"
|
||||
```
|
||||
|
||||
Then, in the returned JSX add a new case to the switch statement:
|
||||
|
||||
```jsx
|
||||
switch (cm.internal.type) {
|
||||
//...
|
||||
case "ContentfulRichText":
|
||||
return <RichText key={cm.id} data={cm} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
If the content model of a tile is Rich Text, you’ll display it with the `RichText` component.
|
||||
|
||||
Finally, to retrieve all necessary data of the Rich Text content, in the `query` GraphQL variable add the following after the `... on ContentfulTileSection` fragment:
|
||||
|
||||
```jsx
|
||||
export const query = graphql`
|
||||
# find the following line
|
||||
... on ContentfulTileSection {
|
||||
|
||||
}
|
||||
# add the following
|
||||
... on ContentfulRichText {
|
||||
id
|
||||
body {
|
||||
raw
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
```
|
||||
|
||||
### Test Rich Text in Page Content
|
||||
|
||||
To test this out, run your Medusa server by running this command in its directory:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
Then run the Gatsby storefront by running this command in its directory:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
This runs the Gatsby storefront on `localhost:8000`. Go to the storefront in your browser and open the About page. You should see the Rich Text content you added.
|
||||
|
||||

|
||||
|
||||
### Render Component in a Product Page
|
||||
|
||||
In the example migration, you also edited the product page to include a new Content Modules field that allows inserting Rich Text content.
|
||||
|
||||
To render them on the Product Page, add the following in the GraphQL query defined in the `query` variable inside `product`:
|
||||
|
||||
```jsx
|
||||
export const query = graphql`
|
||||
query ($id: String!) {
|
||||
product: contentfulProduct(id: { eq: $id }) {
|
||||
# Other fields
|
||||
contentModules {
|
||||
... on ContentfulRichText {
|
||||
id
|
||||
body {
|
||||
raw
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
If you added other accepted Content Models to the `contentModules` field of the Product content type, make sure to add them here.
|
||||
|
||||
:::
|
||||
|
||||
Then, in `src/views/product.js` import the `RichText` component:
|
||||
|
||||
```jsx
|
||||
import RichText from "../components/rich-text/rich-text"
|
||||
```
|
||||
|
||||
And in the returned JSX add the following before the last `</div>`:
|
||||
|
||||
```jsx
|
||||
<div className={styles.contentModules}>
|
||||
{product.contentModules?.map((cm) => {
|
||||
switch (cm.internal.type) {
|
||||
case "ContentfulRichText":
|
||||
return <RichText key={cm.id} data={cm} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
If you added other accepted Content Models to the `contentModules` field of the Product content type, make sure to add cases for them here to display them.
|
||||
|
||||
:::
|
||||
|
||||
This loops over `contentModules` and if the type of the content is Rich Text, it is rendered with the `RichText` component.
|
||||
|
||||
### Test Rich Text on a Product Page
|
||||
|
||||
Restart the Gatsby storefront then open a product that you added Rich Text content to. You should see the Rich Text component at the end of the page.
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
|
||||
- Learn how to deploy your Medusa server to [Heroku](../../deployments/server/deploying-on-heroku.mdx), [Qovery](../../deployments/server/deploying-on-qovery.md), or [DigitalOcean](../../deployments/server/deploying-on-digital-ocean.md).
|
||||
- Learn [how to deploy your Gatsby storefront to Netlify](../../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
281
docs/content/add-plugins/contentful/index.md
Normal file
281
docs/content/add-plugins/contentful/index.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# Contentful
|
||||
|
||||
In this document, you’ll learn how to integrate a Medusa server with Contentful to add rich CMS functionalities
|
||||
|
||||
## Overview
|
||||
|
||||
[Contentful](https://www.contentful.com/) is a headless CMS service that allows developers to integrate rich CMS functionalities into any platform.
|
||||
|
||||
By integrating Contentful to Medusa, you can benefit from powerful features in your ecommerce store including detailed product CMS details, easy-to-use interface to use for static content and pages, localization, and much more.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Needed Accounts
|
||||
|
||||
- [Contentful](https://www.contentful.com/sign-up/) account with a space created. A space is created by default when you create a new account.
|
||||
|
||||
### Required Tools
|
||||
|
||||
- PostgreSQL with an empty database created. You can follow [this documentation to learn how to install it for your operating system](../../tutorial/0-set-up-your-development-environment.mdx#postgres).
|
||||
- Redis. You can follow [this documentation to learn how to install it for your operating system](../../tutorial/0-set-up-your-development-environment.mdx#redis).
|
||||
- Git’s CLI tool. You can follow [this documentation to learn how to install it for your operating system](../../tutorial/0-set-up-your-development-environment.mdx#git).
|
||||
- Gatsby’s CLI tool. You can follow [this documentation to install it](https://www.gatsbyjs.com/docs/reference/gatsby-cli/#how-to-use-gatsby-cli).
|
||||
- Medusa’s CLI tool. You can follow [this documentation to install it](../../cli/reference.md#how-to-install-cli-tool).
|
||||
|
||||
## Install Medusa Server Using Contentful Starter
|
||||
|
||||
Instead of using the default Medusa Server starter, you must use the [Contentful starter](https://github.com/medusajs/medusa-starter-contentful) to install a server that is ready to be used with Contentful. This server contains all the necessary files to make the integration work.
|
||||
|
||||
In your terminal, run the following command to install the server:
|
||||
|
||||
```bash
|
||||
medusa new medusa-contentful https://github.com/medusajs/medusa-starter-contentful
|
||||
```
|
||||
|
||||
This installs a new Medusa server in the directory `medusa-contentful`.
|
||||
|
||||
### Add Contentful Environment Variables
|
||||
|
||||
Change to the `medusa-contentful` directory. In `.env` you’ll find 3 variables:
|
||||
|
||||
```bash
|
||||
CONTENTFUL_SPACE_ID=
|
||||
CONTENTFUL_ACCESS_TOKEN=
|
||||
CONTENTFUL_ENV=
|
||||
```
|
||||
|
||||
#### Value of CONTENTFUL_ENV
|
||||
|
||||
Set the value for `CONTENTFUL_ENV` to `master`.
|
||||
|
||||
#### Value of CONTENTFUL_SPACE_ID
|
||||
|
||||
To retrieve the value of `CONTENTFUL_SPACE_ID`, go to your [Contentful Space dashboard](https://app.contentful.com/). Then, choose Settings in the navigation bar and select API keys from the dropdown.
|
||||
|
||||

|
||||
|
||||
On the APIs page, click Add API Key.
|
||||
|
||||

|
||||
|
||||
In the form, enter a name for the API key and click Save.
|
||||
|
||||

|
||||
|
||||
Then, copy the value of Space ID and set it as the value of `CONTENTFUL_SPACE_ID`.
|
||||
|
||||
#### Value of CONTENTFUL_ACCESS_TOKEN
|
||||
|
||||
Go back to the API Keys page and click on the Content management tokens tab.
|
||||
|
||||

|
||||
|
||||
Click on Generate personal token. A pop-up will open where you have to enter a name for the token.
|
||||
|
||||

|
||||
|
||||
Once you click Generate, a personal access token will be generated. Use it to set the value of `CONTENTFUL_ACCESS_TOKEN`.
|
||||
|
||||
:::warning
|
||||
|
||||
Once you close the pop-up, you won’t be able to get the value of the personal access token again. Make sure to copy it first.
|
||||
|
||||
:::
|
||||
|
||||
### Configure Redis
|
||||
|
||||
In `.env` set the value of your Redis URL:
|
||||
|
||||
```bash
|
||||
REDIS_URL=<YOUR_REDIS_URL>
|
||||
```
|
||||
|
||||
Where `<YOUR_REDIS_URL>` is the URL of your Redis service.
|
||||
|
||||
:::tip
|
||||
|
||||
The default Redis URL is `redis://localhost:6379`.
|
||||
|
||||
:::
|
||||
|
||||
### Configure PostgreSQL
|
||||
|
||||
In `.env` set the value of your PostgreSQL URL:
|
||||
|
||||
```bash
|
||||
DATABASE_URL=<YOUR_DB_URL>
|
||||
```
|
||||
|
||||
Where `<YOUR_DB_URL>` is the URL of your PostgreSQL database.
|
||||
|
||||
:::tip
|
||||
|
||||
You can find the format of the PostgreSQL database URL in [PostgreSQL’s documentation](https://www.postgresql.org/docs/current/libpq-connect.html).
|
||||
|
||||
:::
|
||||
|
||||
Then, in `medusa-config.js` in the exported object, comment out or remove the SQLite database configurations and add the PostgreSQL database configurations:
|
||||
|
||||
```jsx
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
//...
|
||||
database_url: DATABASE_URL,
|
||||
database_type: "postgres",
|
||||
//REMOVE OR COMMENT OUT THE BELOW:
|
||||
// database_database: "./medusa-db.sql",
|
||||
// database_type: "sqlite",
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Migrate Content Types to Contentful
|
||||
|
||||
The Contentful starter provides the necessary scripts to create content types in your Contentful space.
|
||||
|
||||
Run the following commands to migrate the content types into Contentful:
|
||||
|
||||
```bash
|
||||
npm run migrate:contentful
|
||||
```
|
||||
|
||||
Once this command finishes executing, in your Contentful Space dashboard click on Content Model in the navigation bar. You should see a list of new content models added.
|
||||
|
||||

|
||||
|
||||
### Seed Content to Contentful
|
||||
|
||||
The next step is to seed the Contentful Space with some content data.
|
||||
|
||||
Run the following command to seed some data into it:
|
||||
|
||||
```bash
|
||||
npm run seed:contentful
|
||||
```
|
||||
|
||||
After this command finishes running, in your Contentful Space dashboard click on Content in the navigation bar. You should see a list of new content added.
|
||||
|
||||

|
||||
|
||||
### (Optional) Seed Medusa Database
|
||||
|
||||
This step seeds your Medusa database with demo data to easily add products as well as other data to your Medusa server.
|
||||
|
||||
Run the following command to seed the Medusa database:
|
||||
|
||||
```bash
|
||||
npm run seed
|
||||
```
|
||||
|
||||
### Start the Server
|
||||
|
||||
To start the server run the following command:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
If you seeded the database with demo data, you should see that events related to the products are triggered.
|
||||
|
||||

|
||||
|
||||
The Contentful integration ensures a two-way sync between the Medusa server and Contentful. So, when new products are added to Medusa, these products will be added to your Contentful Space as well.
|
||||
|
||||
## (Optional) Add Products with the Medusa Admin
|
||||
|
||||
Using the Medusa admin, you can add products to your Medusa server. This will trigger product events that subsequently add these products to Contentful.
|
||||
|
||||
## Manage Contentful Data
|
||||
|
||||
### Publish Products
|
||||
|
||||
Products added through the integration with the Medusa server are by default saved as drafts. To show them on the storefront, you must set them as published.
|
||||
|
||||
To do that, open your Contentful Space Dashboard and click on Content in the Navigation bar. Then, change Any to Product in the select field next to the search bar. This shows only the content of the type Product, rather than all content.
|
||||
|
||||
Click on the checkbox at the top of the table to select all products then click Publish to publish these products.
|
||||
|
||||

|
||||
|
||||
### Added Featured Products
|
||||
|
||||
On the homepage of the storefront, there’s a featured products tile that shows a set of products. Before running the storefront, you must add at least one product to the list.
|
||||
|
||||
To do that, open your Contentful Space Dashboard and click on Content in the Navigation bar. Make sure the select field next to the search bar is set to Any and search for Featured Products. You should find one content of the type Tile Section.
|
||||
|
||||

|
||||
|
||||
Click on it. You should find on the page an empty Tiles section where you can add tiles and products.
|
||||
|
||||

|
||||
|
||||
Click on Add content then on Add existing content and pick some of the products you want to show on the homepage.
|
||||
|
||||

|
||||
|
||||
Once you’re done adding products, click on Publish changes in the right sidebar.
|
||||
|
||||

|
||||
|
||||
## Setup Gatsby Storefront
|
||||
|
||||
In this section, you’ll set up the Gatsby storefront of your Medusa server.
|
||||
|
||||
In your terminal in a different directory of the Medusa server, run the following command:
|
||||
|
||||
```bash
|
||||
gatsby new medusa-contentful-storefront https://github.com/medusajs/medusa-contentful-storefront
|
||||
```
|
||||
|
||||
This will install the storefront in the directory `medusa-contentful-storefront`.
|
||||
|
||||
### Set Contentful Environment Variables
|
||||
|
||||
Change to the newly created directory and rename `.env.template`:
|
||||
|
||||
```bash
|
||||
mv .env.template .env
|
||||
```
|
||||
|
||||
Then, open `.env`. You should find the following environment variables:
|
||||
|
||||
```bash
|
||||
CONTENTFUL_SPACE_ID=
|
||||
CONTENTFUL_ACCESS_TOKEN=
|
||||
```
|
||||
|
||||
The value of `CONTENTFUL_SPACE_ID` is the same value you [retrieved while setting up the Medusa server](#value-of-contentful_space_id).
|
||||
|
||||
To retrieve the value of `CONTENTFUL_ACCESS_TOKEN`, on your Contentful Space dashboard click on Settings then API keys. Then, choose the API key you created in the previous section.
|
||||
|
||||
You should find the field "Content Delivery API - access token”. Copy its value and set it as the value of `CONTENTFUL_ACCESS_TOKEN`.
|
||||
|
||||

|
||||
|
||||
### Start Storefront
|
||||
|
||||
Make sure the Medusa server is still running. Then, start the storefront:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
This starts the storefront at `localhost:8000`. Open it in your browser and you should see on the homepage the Featured Product section with the products you chose on Contentful.
|
||||
|
||||

|
||||
|
||||
## Make Changes to Content
|
||||
|
||||
You can update the CMS content of your storefront in your Contentful Space. This includes the CMS pages or product details.
|
||||
|
||||
:::note
|
||||
|
||||
If you make changes to the data while your Gatsby storefront is running, the changes are not reflected instantly. That’s because the data is fetched from Contentful during build time. Instead, you must restart your Gatsby storefront to see the changes you make.
|
||||
|
||||
:::
|
||||
|
||||
## What’s Next :rocket:
|
||||
|
||||
- Learn [how to customize your Contentful server and storefront](./customize-contentful.md).
|
||||
- Learn how to deploy your Medusa server to [Heroku](../../deployments/server/deploying-on-heroku.mdx), [Qovery](../../deployments/server/deploying-on-qovery.md), or [DigitalOcean](../../deployments/server/deploying-on-digital-ocean.md).
|
||||
- Learn [how to deploy your Gatsby storefront to Netlify](../../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
@@ -110,6 +110,12 @@ If you haven’t deployed your Medusa server yet, you can leave the value blank
|
||||
|
||||

|
||||
|
||||
:::note
|
||||
|
||||
If you use more environment variables in your storefront be sure to add them here.
|
||||
|
||||
:::
|
||||
|
||||
Once you’re done, scroll down and click on Deploy site.
|
||||
|
||||
You’ll be then redirected to the dashboard of the new website. Netlify will build your website in the background. You should see “Site deploy in progress” on the top card.
|
||||
@@ -237,6 +243,12 @@ netlify env:set GATSBY_MEDUSA_BACKEND_URL "<YOUR_SERVER_URL>"
|
||||
|
||||
Where `<YOUR_SERVER_URL>` is the URL of your Medusa server.
|
||||
|
||||
:::note
|
||||
|
||||
If you use more environment variables in your storefront be sure to add them here.
|
||||
|
||||
:::
|
||||
|
||||
#### Check deployment status
|
||||
|
||||
You can check the deployment status of your website by running the following command:
|
||||
|
||||
@@ -1,328 +0,0 @@
|
||||
---
|
||||
title: Create a headless ecommerce store with Gatsby, Contentful & Medusa
|
||||
---
|
||||
|
||||
# Creating a headless ecommerce store with Gatsby, Contentful and Medusa
|
||||
|
||||
:::info About Medusa
|
||||
|
||||
Medusa is an open source headless commerce engine that allow you to create amazing digital commerce experiences. Medusa is highly customizable, allowing you to extend the core to fit your needs.
|
||||
|
||||
:::
|
||||
|
||||
## Introduction
|
||||
|
||||
In this guide we will go over how to set up a modern e-commerce store using [Gatsby](https://gatsby.com) as a front end, [Contentful](https://contentful.com) as a CMS system and Medusa as a store engine. The resulting e-commerce store will be blazingly fast, highly extendable and will provide the necessary foundation to grow and evolve your e-commerce stack as your business expands to new markets and develops new software requirements.
|
||||
|
||||
## Overview
|
||||
|
||||
After following the steps outlines in this series you will have:
|
||||
|
||||
- A Medusa store engine capable of managing products, processing orders, handling orders and integrating with all the tools in your e-commerce stack.
|
||||
- A statically generated Gatsby storefront that is on brand and customizable from homepage to checkout flow.
|
||||
- A headless CMS system that can be modified and extended to create the best customer experience.
|
||||
|
||||
You will make use of `medusa-plugin-contentful` which is a plugin to your Medusa store engine that syncronizes products and product variants between your Medusa engine and your Contentful space. This allows you to perform content enrichment in Contentful while keeping your core master data in Medusa, for a truly headless commerce setup.
|
||||
|
||||
Other concepts that will be covered in this series include:
|
||||
|
||||
- Gatsby plugins and [File System Route API](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/)
|
||||
- [Contentful Migrations](https://www.contentful.com/developers/docs/tutorials/cli/scripting-migrations/)
|
||||
- Medusa payments, fulfillments and plugins
|
||||
|
||||
If you want to jump straight to the code for this series you can checkout:
|
||||
|
||||
- [`medusa-starter-contentful`](https://github.com/medusajs/medusa-starter-contentful)
|
||||
- [`medusa-contentful-storefront`](https://github.com/medusajs/medusa-contentful-storefront)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
:::note
|
||||
|
||||
For a full guide to how to set up your development environment for Medusa please see [the tutorial](https://docs.medusajs.com/tutorials/set-up-your-development-environment)
|
||||
|
||||
:::
|
||||
|
||||
In order to get you started with your Gatsby, Contentful, Medusa store you must complete a couple of installations:
|
||||
|
||||
- Install the Medusa CLI
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/medusa-cli -g
|
||||
```
|
||||
|
||||
- Install the Gatsby CLI
|
||||
|
||||
```bash npm2yarn
|
||||
npm install gatsby-cli -g
|
||||
```
|
||||
|
||||
- [Create a Contentful account](https://www.contentful.com/sign-up/)
|
||||
- [Install Redis](https://redis.io/topics/quickstart)
|
||||
|
||||
```
|
||||
brew install redis
|
||||
brew services start redis
|
||||
```
|
||||
|
||||
Medusa has support for SQLite and PostgreSQL and uses Redis for caching and queueing of asynchronous tasks. Redis is required for `medusa-plugin-contentful` to work correctly.
|
||||
|
||||
## Setting up your Medusa server
|
||||
|
||||
We will make use of `medusa new` to setup your local Medusa server.
|
||||
|
||||
```bash
|
||||
medusa new medusa-contentful-store https://github.com/medusajs/medusa-starter-contentful
|
||||
```
|
||||
|
||||
This command will setup a new directory at `medusa-contentful-store`, clone the `medusa-starter-contentful` into that directory and install the dependencies for the project.
|
||||
|
||||
### What's inside
|
||||
|
||||
You can now do `cd medusa-contentful-store` and open up your project in your text editor. Below is an overview of the directory structure and a walkthrough of what the different files do.
|
||||
|
||||
```
|
||||
medusa-contentful-store
|
||||
├── contentful-migrations
|
||||
| ├── hero.js
|
||||
| ├── index.js
|
||||
| ├── link.js
|
||||
| ├── navigation-item.js
|
||||
| ├── navigation-menu.js
|
||||
| ├── page.js
|
||||
| ├── product-variant.js
|
||||
| ├── product.js
|
||||
| ├── region.js
|
||||
| ├── tile-section.js
|
||||
| └── tile.js
|
||||
├── data
|
||||
| ├── contentful-seed.json
|
||||
| └── seed.json
|
||||
├── src
|
||||
| ├── api
|
||||
| ├── loaders
|
||||
| ├── services
|
||||
| └── subscribers
|
||||
├── .env
|
||||
├── medusa-config.js
|
||||
├── package.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
#### `package.json`
|
||||
|
||||
If you are familiar with Node you will probably notice that your Medusa store is simply a Node project. Looking inside the `package.json` file you will find that one of the packages that is installed in the project is the `@medusajs/medusa` package. This is the core Medusa package that comes prepacked with all the functionality necessary to do digital commerce - it is also this package that makes sure to register and use the plugins and custom functionality that are configured for your store.
|
||||
|
||||
#### `medusa-config.js`
|
||||
|
||||
Your plugins and store configuration is managed in the `medusa-config.js`, if you open up the file you will see that `medusa-plugin-contentful` is configured with options as shown below. Later we will be setting up your Contentful space so that we can add the necessary environment variables to your `.env` file.
|
||||
|
||||
```javascript
|
||||
// medusa-config.js
|
||||
|
||||
// Contentful Variables
|
||||
const CONTENTFUL_SPACE_ID = process.env.CONTENTFUL_SPACE_ID || "";
|
||||
const CONTENTFUL_ACCESS_TOKEN = process.env.CONTENTFUL_ACCESS_TOKEN || "";
|
||||
const CONTENTFUL_ENV = process.env.CONTENTFUL_ENV || "";
|
||||
|
||||
|
||||
const plugins = [
|
||||
...,
|
||||
{
|
||||
resolve: `medusa-plugin-contentful`,
|
||||
options: {
|
||||
space_id: CONTENTFUL_SPACE_ID,
|
||||
access_token: CONTENTFUL_ACCESS_TOKEN,
|
||||
environment: CONTENTFUL_ENV,
|
||||
},
|
||||
},
|
||||
...
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
redis_url: REDIS_URL,
|
||||
database_database: "./medusa-db.sql",
|
||||
database_type: "sqlite",
|
||||
store_cors: STORE_CORS,
|
||||
admin_cors: ADMIN_CORS,
|
||||
},
|
||||
plugins,
|
||||
};
|
||||
```
|
||||
|
||||
#### `/src`
|
||||
|
||||
In the `/src` directory there are 4 special subdirectories that are added for you already. These special directories can be used to add custom functionality to your store. Custom functionality can include custom endpoints (configured in `/api`), custom business logic (configured in `/services`), pub/sub-like subscriptions for asyncrhonous integration tasks (configured in `/subscribers`) and finally loader functions to be called when your Medusa server starts up (configured in `/loaders`). If you want to learn more about how to add custom functionality you can checkout [the tutorial](https://docs.medusajs.com/tutorials/adding-custom-functionality).
|
||||
|
||||
#### `/data`
|
||||
|
||||
We will be using two seed scripts to kickstart your development, namely:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run seed:contentful
|
||||
npm run seed
|
||||
```
|
||||
|
||||
Data for these seed scripts are contained in the `/data` directory.
|
||||
|
||||
When the seed scripts have been executed you will have a Contentful space that holds all the data for your website; this includes content for Pages, Navigtion Menu, etc.
|
||||
|
||||
#### `/contentful-migrations`
|
||||
|
||||
This directory contains scripts that create content types in your Contentful space. Contentful allows you to customize your content types with fields that can be used to hold all sorts of data, this makes it possible to create advanced data structures that will later be used to lay out your website. Writing migration scripts to evolve your content types is a really powerful tool as you can use it in CI/CD pipelines and makes your projects much more portable.
|
||||
|
||||
The migrations included in this project will create the following content types:
|
||||
|
||||
- **Page**: Represents a page on your website. Each page has a title and can take any number of "Content Modules". Content Modules can be either of the type Hero or Tile Section.
|
||||
- **Hero**: a component that can take a Title, CTA and a background image.
|
||||
- **Tile**: a component that can be added to a Tile Section and renders a Title, CTA and an Image.
|
||||
- **Tile Section**: a component that can hold a number of Tiles or Products. When used with a Product, the Tile Section will display the product thumbnail and it's title and will link to the product page.
|
||||
- **Link**: a component that can link to an external or internal path; or, alternatively, hold a reference to a Page or Product entry. If used with Page or Product, the link path will be inferred from the referenced entry.
|
||||
- **Navigation Item**: an item to include in a Navigation Menu. Each navigation item has a title that can be displayed in a menu and a link that defines where the user will be navigated to when the item is clicked.
|
||||
- **Product**: represents a product as syncronized from Medusa. A product's variants will be copied over as well.
|
||||
- **Product Variant**: The variants of a product.
|
||||
- **Region**: Represents an available region in Medusa.
|
||||
|
||||
## Creating a Contentful space
|
||||
|
||||
To create a new Contentful space log in to your Contentful account. If you already have a Contentful account with a Space configured you can click your organization name in the top left corner to reveal an overview of your organization's spaces. At the bottom of the spaces list you should click "Add space".
|
||||
|
||||
**Select "Community space" and "Web app only"**
|
||||
In this guide we will be using a free space which gives you an incredibly strong foundation for creating on-brand customer experiences and advances shopping flows.
|
||||
|
||||

|
||||
|
||||
**Add a name and select "Empty space"**
|
||||
|
||||

|
||||
|
||||
Once your space is set up you can go to your space home. We will now get the credentials needed for `medusa-plugin-contentful` to work.
|
||||
|
||||
Open your `.env` file in your text editor you should see:
|
||||
|
||||
```shell
|
||||
# .env
|
||||
JWT_SECRET=something
|
||||
COOKIE_SECRET=something
|
||||
|
||||
STRIPE_API_KEY=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
|
||||
CONTENTFUL_SPACE_ID=
|
||||
CONTENTFUL_ACCESS_TOKEN=
|
||||
CONTENTFUL_ENV=
|
||||
```
|
||||
|
||||
Your `CONTENTFUL_SPACE_ID` can be found by going to your space home and checking your browser's URL bar. The space id is the alphanumeric string following `https://app.contentful.com/spaces/`. Copy this string and paste it into your `.env` file.
|
||||
|
||||
To get your `CONTENFUL_ACCESS_TOKEN` go to your space home and click **Settings** > **API keys**
|
||||
|
||||

|
||||
|
||||
Then click **Content management tokens** and click **Generate personal token**. After giving your token a name you can copy it to your `.env`
|
||||
|
||||

|
||||
|
||||
For `CONTENTFUL_ENVIRONMENT` add `master`.
|
||||
|
||||
You should now have a `.env` that looks like this:
|
||||
|
||||
```shell
|
||||
# .env
|
||||
JWT_SECRET=something
|
||||
COOKIE_SECRET=something
|
||||
|
||||
STRIPE_API_KEY=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
|
||||
CONTENTFUL_SPACE_ID=****
|
||||
CONTENTFUL_ACCESS_TOKEN=CFPAT-*******
|
||||
CONTENTFUL_ENV=master
|
||||
```
|
||||
|
||||
## Migrating and Seeding your Contentful space
|
||||
|
||||
Now that we have collected your credentials we are ready to migrate the Contentful space to add the content types we talked about earlier. To migrate the Contentful space open up your command line and `cd` into `medusa-contentful-store`.
|
||||
|
||||
You can now run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run migrate:contentful
|
||||
```
|
||||
|
||||
This script will run each of the migrations in the `contentful-migrations` directory. After it has completed navigate to your Contentful space and click "Content model" in the top navigation bar. You will see that the content types will be imported into your space. Feel free to familiarize yourself with the different types by clicking them and inspecting the different fields that they hold.
|
||||
|
||||

|
||||
|
||||
The next step is to seed the Contentful space with some data that can be used to display your ecommerce store's pages and navigation. To seed the database open up your command line and run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run seed:contentful
|
||||
```
|
||||
|
||||
In your Contentful space navigate to "Content" and you will be able to see the different entries in your space. You can filter the entries by type to, for example, only view Pages:
|
||||
|
||||

|
||||
|
||||
You will notice that there are not any Products in your store yet and this is because we haven't created any products in your Medusa store.
|
||||
|
||||
To do this open your command line and run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run seed
|
||||
npm run start
|
||||
```
|
||||
|
||||
This will seed your Medusa database, which will result in `medusa-plugin-contentful` synchronizing data to your Contentful space. Everytime you add or update a product the data will be copied into your Contentful space for further enrichment.
|
||||
|
||||
## Setting Featured Products
|
||||
|
||||
In Contentful navigate to "Content" and find the Page called "Home". We will now add some featured products to the home page.
|
||||
|
||||
- Click the "Home" entry and scroll down to the field called "Content modules"
|
||||

|
||||
|
||||
- Click the Content module named "Featured Products" and click "Add content" in the "Tiles" field
|
||||

|
||||
|
||||
- Click "Add existing content" as e will be adding the products that were copied over by Medusa
|
||||

|
||||
|
||||
- Select Medusa Waterbottle and Medusa Shirt and click "Insert 2 entries"
|
||||
|
||||
Make sure that everything is published by hitting publish in the sidebar on the right-hand side.
|
||||
|
||||
## Setting up your Gatsby storefront
|
||||
|
||||
Now that we have your Medusa server running and your Contentful space seeded with some starter data it is time to add a presentational layer that can be used by customers to browse and purchase the items in your store.
|
||||
|
||||
We have already created the storefront and you can install and use it by simply running:
|
||||
|
||||
```
|
||||
gatsby new medusa-contentful-storefront https://github.com/medusajs/medusa-contentful-storefront
|
||||
```
|
||||
|
||||
Once `gatsby new` is complete you should rename the `.env.template` file to `.env` and add a Content Delivery token. Your content delivery token is different from the personal access token you generated earlier, so make sure that you are using the correct token when you paste it into your `.env`.
|
||||
|
||||
To get your token go to **Settings** > **API Keys** > **Add API key**. Now click save and copy the token specified in the field "Content Delivery API - access token".
|
||||
|
||||
After you have copied the token and your space ID to your `.env`, you can start your Gatsby development server on port 8000 by running:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run start
|
||||
```
|
||||
|
||||
You can now go to https://localhost:8000 to check out your new Medusa store.
|
||||
|
||||

|
||||
|
||||
## Summary
|
||||
|
||||
Using three powerful tools we have now set up a modern headless ecommerce store on our local development machine. This setup can scale with your business's needs and evolve to fit create amazing commerce expereiences that are unique and on brand. The steps we took in this guide were really simple and fast: first we created a Medusa server using the Medusa CLI, we then configured a Contentful space by running migrations and seed scripts. We also installed a Gatsby front end for our Medusa store using the Gatsby CLI.
|
||||
|
||||
## What's next
|
||||
|
||||
In the next part we will dig deeper into how Contentful can be used to create pages, enrich your products and structure your content. We will also take a look at the files in your Gatsby storefront.
|
||||
|
||||
Stay tuned!
|
||||
@@ -1,316 +0,0 @@
|
||||
---
|
||||
title: Making your store more powerful with Contentful
|
||||
---
|
||||
|
||||
# Making your store more powerful with Contentful
|
||||
|
||||
In [part 1](https://docs.medusajs.com/how-to/headless-ecommerce-store-with-gatsby-contentful-medusa/) of this series you have set up [Medusa](https://medusajs.com) with Contentful as your CMS system and added a Gatsby storefront. In this part you will get a further introduction to Contentful and learn how [`medusa-plugin-contentful`](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-contentful) can be leveraged to make your store more powerful. Apart from a front page, product pages and a checkout flow, most ecommerce stores also need miscalleneous pages like About and Contact pages. In this guide you will add a Rich Text content module to your Contentful space so that you can make this pages cool. You will also see how the content modules can be used to give your product pages more life.
|
||||
|
||||
What you will do in this guide:
|
||||
|
||||
- Add a rich text content module
|
||||
- Add rich text to your `/about` page
|
||||
- Add a "Related Products" section to your product page
|
||||
|
||||
Topics covered:
|
||||
|
||||
- Contentful Migrations
|
||||
- Product enrichment
|
||||
|
||||
## Creating a rich text content module
|
||||
|
||||
In this guide you will make use of [Contentful Migrations](https://github.com/contentful/contentful-migration) to keep a versioned controlled record of how your Content evolves over time. The Contentful app allows you to create content models straight from their dashboard, however, when using the migrations tool you will be able to 1) quickly replicate your Contentful space and 2) incorporate migrations as part of a CI/CD pipeline. [You can read more about how to use CMS as Code here](https://www.contentful.com/help/cms-as-code/).
|
||||
|
||||
To prepare your migration create a new file at `contentful-migrations/rich-text.js` and add the following code:
|
||||
|
||||
```javascript
|
||||
// contentful-migrations/rich-text.js
|
||||
|
||||
module.exports = function (migration, context) {
|
||||
const richText = migration
|
||||
.createContentType("richText")
|
||||
.name("Rich Text")
|
||||
.displayField("title")
|
||||
|
||||
richText.createField("title").name("Title (Internal)").type("Symbol")
|
||||
richText.createField("body").name("Body").type("RichText")
|
||||
}
|
||||
```
|
||||
|
||||
This small snippet will create a content model in your Contentful space with two fields: a title which will be used to name entries in a meaningful manner (i.e. it won't be displayed to customers) and a body which contains the rich text to display. To apply your migration run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run migrate:contentful --file contentful-migrations/rich-text.js
|
||||
```
|
||||
|
||||
If you go to your Contentful space and click Content Model you will see that the Rich Text model has been added to your space:
|
||||

|
||||
|
||||
The validation rules in the Page model only allow Hero and Tile Sections to be added to the Content Modules fields so you will need another migration to make it possible for pages to make use of the new Rich Text modules. Create a new migration at `contentful-migrations/update-page-module-validation.js` and add the following:
|
||||
|
||||
```javascript
|
||||
// contentful-migrations/update-page-module-validation.js
|
||||
|
||||
module.exports = function (migration, context) {
|
||||
const page = migration.editContentType("page")
|
||||
|
||||
page.editField("contentModules").items({
|
||||
type: "Link",
|
||||
linkType: "Entry",
|
||||
validations: [
|
||||
{
|
||||
linkContentType: ["hero", "tileSection", "richText"],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
After migrating your space you are ready create your new contact page:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run migrate:contentful --file contentful-migrations/update-page-module-validation.js
|
||||
```
|
||||
|
||||
## Adding Rich Text to About
|
||||
|
||||
To use your new Rich Text module **Content > Page > About**, and click **Add Content > Page**. You will now make use of the new Rich Text module to add some more details about your store. You can write your own text or use the text provided below if you just want to copy/paste.
|
||||
|
||||
:::info About Medusa
|
||||
|
||||
Medusa is an open-source headless commerce engine for fast-growing businesses. Getting started with Medusa is very easy and you will be able to start selling online with a basic setup in no time, however, the real power of Medusa starts showing up when you add custom functionality and extend your core to fit your needs.
|
||||
|
||||
The core Medusa package and all the official Medusa plugins ship as individual NPM packages that you install into a Node project. You store and plugins are configured in your medusa-config.js file making it very easy to manage your store as your business grows. Custom functionality doesn't have to come from plugins, you can also add project-level functionality by simply adding files in your `src/` folder. Medusa will automatically register your custom functionalities in the bootstrap phase.
|
||||
|
||||
:::
|
||||
|
||||

|
||||
|
||||
When you have added your text you can click **Publish changes** (make sure the About page is published too).
|
||||
|
||||
## Updating the storefront to support the Rich Text module
|
||||
|
||||
:::note
|
||||
|
||||
If you want to jump straight to the final frontend code visit [medusajs/medusa-contentful-storefront@part-2](https://github.com/medusajs/medusa-contentful-storefront/tree/part-2).
|
||||
|
||||
:::
|
||||
|
||||
To display your newly created Rich Text module open up the storefront code and create a new file at `src/components/rich-text/rich-text.jsx`.
|
||||
|
||||
```jsx
|
||||
// src/components/rich-text/rich-text.jsx
|
||||
|
||||
import React from "react"
|
||||
import { renderRichText } from "gatsby-source-contentful/rich-text"
|
||||
|
||||
import * as styles from "../../styles/rich-text.module.css"
|
||||
|
||||
const RichText = ({ data }) => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
{data.body ? renderRichText(data.body) : ""}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RichText
|
||||
```
|
||||
|
||||
The `renderRichText` function is imported from the `gatsby-source-contentful` plugin to easily transform the text you entered in the Rich Text module to html. To make the Rich Text component render nicely add a style file as well at `src/styles/rich-text.module.css`.
|
||||
|
||||
```css
|
||||
/* src/styles/rich-text.module.css */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: auto;
|
||||
max-width: 870px;
|
||||
}
|
||||
```
|
||||
|
||||
If you restart your storefront server now you will not be able to see your new Rich Text module just yet. The last step to making that happen will be to let the Page component know to render the new Rich Text component when it encounters Rich Text in the Page's Content Modules. In your editor open up the file `src/pages/{ContentfulPage.slug}.js` and add the following:
|
||||
|
||||
At the top of the file import your `RichText` component:
|
||||
|
||||
```javascript
|
||||
...
|
||||
import RichText from "../components/rich-text/rich-text"
|
||||
...
|
||||
```
|
||||
|
||||
Now in the `contentModules.map` function return the `RichText` component whenever a `ContentfulRichText` module is encountered. Add a case to the switch statement:
|
||||
|
||||
```javascript
|
||||
case "ContentfulRichText":
|
||||
return <RichText key={cm.id} data={cm} />
|
||||
```
|
||||
|
||||
Finally you will need to fetch the Rich Text data from Gatsby's data layer by modifying the GraphQL code at the bottom of the file after the line with `contentModules {` add:
|
||||
|
||||
```graphql
|
||||
... on ContentfulRichText {
|
||||
id
|
||||
body {
|
||||
raw
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart your local Gatsby server and visit `http://localhost:8000/about`, you will now see the your newly added Rich Text module.
|
||||
|
||||

|
||||
|
||||
## Enriching your Product pages
|
||||
|
||||
You have now seen how the Page model in Contentful can be extended to include a new content module in a reusable and modular manner. The same idea can be extended to your Product pages allowing you to create completely bespoke universes around your products. You will use the same techniques as above to create a Related Products section below the "Medusa Shirt" product.
|
||||
|
||||
### Migrating Products
|
||||
|
||||
First, add a new field to the Product content model. Using migrations you can create a file `contentful-migrations/product-add-modules.js`:
|
||||
|
||||
```javascript
|
||||
// contentful-migrations/product-add-modules.js
|
||||
|
||||
module.exports = function (migration, context) {
|
||||
const product = migration.editContentType("product")
|
||||
|
||||
product
|
||||
.createField("contentModules")
|
||||
.name("Content Modules")
|
||||
.type("Array")
|
||||
.items({
|
||||
type: "Link",
|
||||
linkType: "Entry",
|
||||
validations: [
|
||||
{
|
||||
linkContentType: ["hero", "tileSection", "richText"],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Run the migration:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run migrate:contentful --file contentful-migrations/product-add-modules.js
|
||||
```
|
||||
|
||||
### Adding "Related Products" Tile Section
|
||||
|
||||
After the migration you can now add Content Modules to Products, to enrich the Product pages with relevant content. In this guide you will add a Tile Section that holds "Related Products", but the functionality could be further extended to showcase look book images, inspirational content or more detailed product descriptions.
|
||||
|
||||
In Contentful go to **Content > Product > Medusa Shirt** scroll all the way to the bottom, where you should be able to find the new _Content Modules_ field:
|
||||
|
||||

|
||||
|
||||
Click **Add content > Tile Section** which will open a new Tile Section. For the Title write "Related Products", and for Tiles click **Add content > Add existing content > Medusa Waterbottle > Insert 1 entry**.
|
||||
|
||||

|
||||
|
||||
Click **Publish** and make sure that the Medusa Shirt product is published too.
|
||||
|
||||
Your data is now ready to be used in the storefront, but you still need to make a couple of changes to the storefront code to be able to view the new content.
|
||||
|
||||
## Adding Content Modules to Product pages
|
||||
|
||||
Just like you did for the Page component, you will have to fetch the Content Modules from Gatsby's GraphQL data layer.
|
||||
|
||||
In the file `src/pages/products/{ContentfulProduct.handle}.js` add the following in the GraphQL query at the bottom of the file (e.g. after the variants query):
|
||||
|
||||
```graphql
|
||||
# src/pages/products/{ContentfulProduct.handle}.js
|
||||
|
||||
contentModules {
|
||||
... on ContentfulTileSection {
|
||||
id
|
||||
title
|
||||
tiles {
|
||||
... on ContentfulProduct {
|
||||
id
|
||||
title
|
||||
handle
|
||||
thumbnail {
|
||||
gatsbyImageData
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
... on ContentfulTile {
|
||||
id
|
||||
title
|
||||
cta
|
||||
image {
|
||||
gatsbyImageData
|
||||
}
|
||||
link {
|
||||
linkTo
|
||||
reference {
|
||||
slug
|
||||
}
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This snippet will query the Content Modules defined for the product and will allow you to use the data in your components.
|
||||
|
||||
Next open up the `src/views/products.jsx` file and add the following snippets.
|
||||
|
||||
Import the `TileSection` component:
|
||||
|
||||
```javascript
|
||||
import TileSection from "../components/tile-section/tile-section"
|
||||
```
|
||||
|
||||
Add the Content Modules in the JSX just before the final closing `div`:
|
||||
|
||||
```jsx
|
||||
// src/views/products.jsx
|
||||
|
||||
<div className={styles.contentModules}>
|
||||
{product.contentModules?.map((cm) => {
|
||||
switch (cm.internal.type) {
|
||||
case "ContentfulTileSection":
|
||||
return <TileSection key={cm.id} data={cm} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
```
|
||||
|
||||
Restart the Gatsby server and visit http://localhost:8000/product/medusa-shirt you should now see the new "Related Products" Tile Section below the Product page controls.
|
||||
|
||||

|
||||
|
||||
## Summary
|
||||
|
||||
In this guide you created a new content model for Rich Text input in Contentful using [contentful-migration](https://github.com/contentful/contentful-migration). You further extended the storefront to render the new Rich Text plugin. The concepts in this guide are meant to demonstrate how Contentful can be used to make your store more powerful in a modular and scalable way. The content modules covered in this guide could be further extended to add other custom modules, for example, you could add a Newsletter Signup, module that when encountered in the code renders a newsletter form.
|
||||
|
||||
## What's next
|
||||
|
||||
In the next part of this guide you will learn how to implement further commerce functionalities to your site such as adding support for discount codes, region based shopping and more. (Coming soon)
|
||||
|
||||
- [Deploying Medusa Server](../deployments/server/index.mdx)
|
||||
- [Deploying Medusa Admin](../deployments/admin/index.mdx)
|
||||
@@ -55,7 +55,7 @@ The server will be installed under the `backend` directory under the project dir
|
||||
|
||||
:::tip
|
||||
|
||||
You can learn more about the Contentful starter in the [Contentful Integration documentation](../add-plugins/contentful.md).
|
||||
You can learn more about the Contentful starter in the [Contentful Integration documentation](../add-plugins/contentful/index.md).
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@@ -329,29 +329,25 @@ module.exports = {
|
||||
label: "CMS",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/contentful",
|
||||
type: "category",
|
||||
label: "Contentful",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "add-plugins/contentful/index",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/contentful/customize-contentful",
|
||||
label: "Customize Contentful Integration",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/strapi",
|
||||
label: "Strapi",
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Gatsby + Contentful + Medusa",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/headless-ecommerce-store-with-gatsby-contentful-medusa",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/making-your-store-more-powerful-with-contentful",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user