docs: documentation changes for release (#4300)

* docs: added manage reservations user guide (#4290)

* docs: added manage reservations user guide

* removed feature flag details

* docs: added how-to for custom reservations (#4292)

* docs: added how-to for custom reservations

* eslint fixes

* docs: added product module documentation (#4287)

* docs: added product module documentation

* added details about optional environment variables

* small fixes

* Remove reference link

* added example usages

* added link to sample project

* address PR feedback

* docs: moved product module guide + added product module tabs (#4307)

* added product module tab

* adjust design of badge

* docs: added onboarding features (#4168)

* added marketplace page

* added subscription roadmap

* added rating for onboarding

* added learning path components

* small fixes

* fix build error

* fix eslint errors

* change roadmaps to recipes

* small change in text

* optimize learning path and notifications

* fix tracking usage

* fix eslint errors

* added enter/exit animation

* allow starting a path using a query parameter

* fix gap between notifications

* address vercel comments

* fixed links issue

* changed create-medusa-app docs steps

* move troubleshooting section

* improved tracking across docs

* fix build errors

* remove console

* added a note about `boilerplate` option

* added troubleshooting section for eagain

* added invite option in cli reference

* added track event for finished onboarding

* update boilerplate option name

* redesigned learning path component

* docs: added how to create widget docs (#4318)

* docs: added how to create widget docs

* remove development guide

* added types

* docs: added details about createCustomAdminHooks (#4288)

* docs: added details about createCustomAdminHooks

* small improvement

* added missing import

* small changes

* docs: added onboarding guide (#4320)

* docs: added how to create widget docs

* remove development guide

* docs: added onboarding guide

* added types

* added recipes link

* small adjustments

* fixed eslint errors

* styling fixes

* change to singular product module

* updated the what's new section

* shorten down medusa react card

* updated tailwind configurations

* fix build error

* fix newspaper icon

* style fixes

* change modal shadow

* fix color of line numbers

* fix code fade color

* docs: updated admin documentations

* eslint fixes

* text changes

* added a note about beta version

* remove empty object argument

* remove demo repo url

* fix selection color for code headers

* general fixes

* fix eslint error

* changed code theme

* added preparation step

* changes regarding beta version

* Update docs/content/modules/products/serverless-module.md

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

* Update docs/content/modules/products/serverless-module.md

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

---------

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>
Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Shahed Nasser
2023-06-20 12:25:22 +02:00
committed by GitHub
co-authored by Riqwan Thamir Oliver Windall Juhl
parent 8db03619b5
commit 76c4bf4acb
177 changed files with 8828 additions and 1196 deletions
+99
View File
@@ -0,0 +1,99 @@
import DocCardList from '@theme/DocCardList';
import DocCard from '@theme/DocCard';
import Icons from '@theme/Icon';
import Feedback from '@site/src/components/Feedback';
import LearningPath from '@site/src/components/LearningPath';
import LargeCard from '@site/src/components/LargeCard';
import Button from '@site/src/components/Button';
# Medusa Recipes
This document provides you resources for different paths based on what you're building with Medusa.
:::note
These recipes assume you already have a Medusa backend setup. If not, you can create a Medusa project with the following command:
```bash
npx create-medusa-app
```
[Learn more in this guide](../create-medusa-app.mdx).
:::
## Recipe: Setup Ecommerce Store
Follow this recipe if you want to use Medusa for an ecommerce store. This recipe includes three steps that will get you a storefront deployed to Vercel and a backend deployed to Railway.
<LearningPath pathName="simple-quickstart" />
---
## Recipe: Build a Marketplace
Follow this guide if you want to build a Marketplace with Medusa.
<DocCard item={{
type: 'link',
href: '/recipes/marketplace',
label: 'Build a Marketplace',
customProps: {
icon: Icons['building-storefront'],
description: 'Learn how you can build a marketplace with Medusa.'
}
}} />
---
## Recipe: Build Subscription Purchases
Follow this guide if you want to implement subscription-based purhcases with Medusa.
<DocCard item={{
type: 'link',
href: '/recipes/subscriptions',
label: 'Build Subscription Purchases',
customProps: {
icon: Icons['credit-card-solid'],
description: 'Learn how you can implement subscription-based purchase in Medusa.'
}
}} />
<Feedback
event="survey_use_cases"
question="Did your find your use case?"
positiveQuestion="Is there anything that should improved?"
negativeQuestion="What was your use case?"
/>
---
<!-- vale docs.HeadingPunctuation = NO -->
## Can't find your path?
<!-- vale docs.HeadingPunctuation = YES -->
Medusa is a customizable commerce solution that can be used to build any custom use case. If you can't find your use case mentioned above, the following guides give you a general understanding of how Medusa can be used and how you can customize it.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/overview',
label: 'Commerce Modules',
customProps: {
icon: Icons['puzzle-solid'],
description: "Learn about Medusa's commerce features and how to customize them."
}
},
{
type: 'link',
href: '#',
label: 'Medusa Development',
customProps: {
icon: Icons['server-stack-solid'],
description: "Learn how about Medusa's architecture and how to customize it."
}
},
]} />
+400
View File
@@ -0,0 +1,400 @@
import DocCardList from '@theme/DocCardList';
import DocCard from '@theme/DocCard';
import Icons from '@theme/Icon';
import LearningPath from '@site/src/components/LearningPath';
# Build a Marketplace
This document guides you through the different documentation resources that will help you build a marketplace with Medusa.
## Overview
A marketplace is an online commerce store that allows different vendors to sell their products within the same commerce system. Customers can purchase products from any of these vendors, and vendors can manage their orders separately.
<LearningPath pathName="marketplace" />
---
## Associate Entities with Stores
:::tip
Entities represent tables in the database.
:::
By default, entities like users, products, or orders aren't associated with a store, as it's assumed there's one store in Medusa. For a marketplace, each of these entities should be associated with their respective stores.
To associate these entities with the `Store` entity, you need to extend and customize entities created in the Medusa core package `@medusajs/medusa`, such as the `User` entity, to add a relation to the `Store` entity.
<DocCard item={{
type: 'link',
href: '/development/entities/extend-entity',
label: 'Extend an Entity',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to extend an entity in Medusa.',
}
}} />
<details>
<summary>Example: Associate User with Store</summary>
For example, to associate the `User` entity with the `Store` entity, create the file `src/models/user.ts` with the following content:
```ts title=src/models/user.ts
import {
Column,
Entity,
Index,
JoinColumn,
ManyToOne,
} from "typeorm"
import {
User as MedusaUser,
} from "@medusajs/medusa"
import { Store } from "./store"
@Entity()
export class User extends MedusaUser {
@Index("UserStoreId")
@Column({ nullable: true })
store_id?: string
@ManyToOne(() => Store, (store) => store.members)
@JoinColumn({ name: "store_id", referencedColumnName: "id" })
store?: Store
}
```
Then, you need to extend the `UserRepository` to point to your extended entity. To do that, create the file `src/repositories/user.ts` with the following content:
```ts title=src/repositories/user.ts
import { User } from "../models/user"
import {
dataSource,
} from "@medusajs/medusa/dist/loaders/database"
import {
UserRepository as MedusaUserRepository,
} from "@medusajs/medusa/dist/repositories/user"
export const UserRepository = dataSource
.getRepository(User)
.extend({
...Object.assign(
MedusaUserRepository,
{ target: User }
),
})
export default UserRepository
```
Next, you need to create a migration that reflects the changes on the `User` entity in your database. To do that, run the following command to create a migration file:
```bash
npx typeorm migration:create src/migrations/add-user-store-id
```
This creates a file in the `src/migrations` directory of the format `<TIMESTAMP>_add-user-store-id.ts`. Replace the `up` and `down` methods in that file with the methods here:
```ts title=src/migrations/<TIMESTAMP>_add-user-store-id.ts
// ...
export class AddUserStoreId1681287255173
implements MigrationInterface {
// ...
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "user" ADD "store_id" character varying`
)
await queryRunner.query(
`CREATE INDEX "UserStoreId" ON "user" ("store_id")`
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP INDEX "public"."UserStoreId"`
)
await queryRunner.query(
`ALTER TABLE "user" DROP COLUMN "store_id"`
)
}
}
```
Finally, to reflect these changes and start using them, `build` your changes and run migrations with the following commands:
```bash npm2yarn
npm run build
npx @medusajs/medusa migrations run
```
You can extend other entities in a similar manner to associate them with a store.
</details>
---
## Accessing Logged-in User
Throughout your development, you'll likely need access to the logged-in user. For example, you'll need to know which user is logged in to know which store to associate a new product with.
<DocCard item={{
type: 'link',
href: '/development/endpoints/example-logged-in-user',
label: 'Access Logged-in User',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to access the logged-in user throughout your project using a Middleware.',
}
}} />
---
## Customize Data Management Functionalities
After associating entities with stores, you'll need to customize how certain data management functionalities are implemented in the Medusa core package.
For example, when a new user is created, you need to ensure that it's associated either with a new store or with the store of the logged-in user. Another example is associating a new product with the logged-in user's store.
You can customize these functionalities by extending services. Services are classes that contain helper methods specific to an entity. For example, the `UserService` is used to manage functionalities related to the `User` entity, such as creating a user.
You can also extend services if you need to customize a functionality implemented in a service for other reasons.
<DocCard item={{
type: 'link',
href: '/development/services/extend-service',
label: 'Extend a Service',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to extend a service in Medusa',
}
}} />
<details>
<summary>Example: Extend User Service</summary>
You can extend the user service to change how the `create` method is implemented.
To extend the user service, create the file `src/services/user.ts` with the following content:
<!-- eslint-disable prefer-rest-params -->
```ts
import { Lifetime } from "awilix"
import {
UserService as MedusaUserService,
} from "@medusajs/medusa"
import { User } from "../models/user"
import {
CreateUserInput as MedusaCreateUserInput,
} from "@medusajs/medusa/dist/types/user"
import StoreRepository from "../repositories/store"
type CreateUserInput = {
store_id?: string
} & MedusaCreateUserInput
class UserService extends MedusaUserService {
static LIFE_TIME = Lifetime.SCOPED
protected readonly loggedInUser_: User | null
protected readonly storeRepository_: typeof StoreRepository
constructor(container, options) {
super(...arguments)
this.storeRepository_ = container.storeRepository
try {
this.loggedInUser_ = container.loggedInUser
} catch (e) {
// avoid errors when backend first runs
}
}
async create(
user: CreateUserInput,
password: string
): Promise<User> {
if (!user.store_id) {
const storeRepo = this.manager_.withRepository(
this.storeRepository_
)
let newStore = storeRepo.create()
newStore = await storeRepo.save(newStore)
user.store_id = newStore.id
}
return await super.create(user, password)
}
}
export default UserService
```
In the `create` method of this extended service, you create a new store if the user being created doesn't have a store associated with it.
You can then test out your customization by running the `build` command and starting the backend:
```bash
npm run build
npx @medusajs/medusa develop
```
</details>
---
## Listening to Events
While implementing your marketplace, you'll typically need to listen to certain events then perform actions asynchronously. For example, you can listen to the `order.placed` event and, when triggered, create child orders of the order, separating ordered items by their associated store.
To listen to events, you need to create Subscribers that subscribe a handler method to an event. In that handler method, you can implement the desired functionality.
<DocCard item={{
type: 'link',
href: '/development/events/create-subscriber',
label: 'Create a Subscriber',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a subscriber in Medusa.',
}
}} />
<details>
<summary>Example: Listen to Order Created Event</summary>
To listen to the `order.placed` event, create the file `src/subscribers/orderNotifier.ts` with the following content:
```ts
class OrderNotifierSubscriber {
constructor({ eventBusService }) {
eventBusService.subscribe("order.placed", this.handleOrder)
}
handleOrder = async (data) => {
// TODO perform functionality
}
}
export default OrderNotifierSubscriber
```
This subscribes the `handleOrder` method to be executed whenever the `order.placed` event is emitted.
You can then test out your subscriber by running the `build` command and starting the backend:
```bash
npm run build
npx @medusajs/medusa develop
```
</details>
---
## Add Payment and Fulfillment Providers
Payment and fulfillment providers can be added through plugins or directly in your project. You can either create your own provider, use one of Medusa's official plugins, or use community plugins.
:::note
Payment and fulfillment providers are associated with regions, which are not associated with a store, by default. If you want to allow each store to specify its own payment and fulfillment providers, you'll need to [associate the region with a store](#associate-entities-with-stores).
:::
### Option 1: Create your own providers
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/carts-and-checkout/backend/add-payment-provider',
label: 'Create a Payment Processor',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a payment processor.',
}
},
{
type: 'link',
href: '/modules/carts-and-checkout/backend/add-fulfillment-provider',
label: 'Create a Fulfillment Provider',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a fulfillment provider.',
}
},
]} />
### Option 2: Install a Plugin
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/plugins/overview',
label: 'Install an Official Medusa Plugin',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Check out available Medusa plugins to install.',
}
},
{
type: 'link',
href: 'https://medusajs.com/plugins/',
label: 'Install a Community Plugin',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Check out available community plugins to install.',
}
},
]} />
---
## Build a Storefront
Medusa provides a Next.js starter storefront that you can use with Medusa. Since you've customized your Medusa project, you'll need to either customize the existing Next.js storefront, or create a custom storefront.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/starters/nextjs-medusa-starter',
label: 'Option 1: Use Next.js Storefront',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Install the Next.js Storefront to customize it.',
}
},
{
type: 'link',
href: '/storefront/roadmap',
label: 'Option 2: Build Custom Storefront',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Find useful resources to build your own storefront.',
}
},
]} />
---
## Deploy Marketplace
Our documentation includes deployment guides for a basic Medusa backend. You should be able to follow it to deploy your customized marketplace, as well.
<DocCard item={{
type: 'link',
href: '/deployments/server',
label: 'Deploy Backend',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to deploy your marketplace backend to different hosting providers.',
}
}} />
---
## Additional Development
You can find other resources for your marketplace development in the [Medusa Development section](../development/overview.mdx) of this documentation.
+161
View File
@@ -0,0 +1,161 @@
import DocCardList from '@theme/DocCardList';
import DocCard from '@theme/DocCard';
import Icons from '@theme/Icon';
import LearningPath from '@site/src/components/LearningPath';
# Build Subscription-based Purchases
This document guides you through the different documentation resources that will help you build subscription-based purchasing in Medusa.
## Overview
Subscription-based purchase allows customers to purchase products for a specified period, and the payment and fulfillment is processed within a regular interval in that period.
For example, a customer can purchase a book subscription box for a period of three months. Each month, the payment will be captured for that order and, if the payment is successful, the fulfillment will be processed.
<LearningPath pathName="subscriptions" />
---
## Save Subscription Details in the Database
Subscriptions have details related to the subscription interval, subscription period, and more.
Based on the approach you choose to implement the subscription logic (which is discussed in the next section), you might need to store different data in your backend.
If you want to store the subscription details in a new table in the database, you can do that by creating an entity. If you want to extend an existing entity in Medusa's core, such as the `Order` entity, to add details related to the subscription, you can extend an entity.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/development/entities/create',
label: "Create an Entity",
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create an entity in Medusa.',
}
},
{
type: 'link',
href: '/development/entities/extend-entity',
label: 'Extend an Entity',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to extend an entity in Medusa.',
}
},
]} />
---
## Decide on Subscription Approach
There are different ways to implement subscriptions in your Medusa backend. This document discusses two options: using Stripe subscriptions, or implementing subscriptions logic within the backend, independent of a specific payment provider.
### Option 1: Using Stripe Subscriptions
Stripe provides a [subscription payments](https://stripe.com/docs/billing/subscriptions/overview) that allows you to authorize payment on a subscription basis within Stripe. Stripe then handles checking for recurring payments and capturing payment at the specified interval.
This approach allows you to deligate the complications of implementing the subscription logic to Stripe, but does not support using other payment providers.
Medusa provides a Stripe plugin, however, it doesn't handle subscriptions. You can either use that plugin to add the subscription feature on top of it, or create a custom Stripe Subscription payment provider.
<DocCardList colSize={6} items={[
{
type: 'link',
href: 'https://github.com/medusajs/medusa/tree/develop/packages/medusa-payment-stripe',
label: "Use Medusa's Stripe Plugin",
customProps: {
icon: Icons['github'],
description: "Check out Medusa's stripe plugin to build subscription on top of it.",
}
},
{
type: 'link',
href: '/modules/carts-and-checkout/backend/add-payment-provider',
label: 'Create Payment Processor',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Create a Stripe Subscription payment processor from scratch.',
}
},
]} />
### Option 2: Implement Subscription Logic
By implementing the subscription logic within your backend, you can have full control over the subscription logic. You'll also be independent of payment providers, allowing you to provide customers with more than payment provider option.
Implementing the logic depends on your use case, but you'll mainly need to do two things:
1. Perform an action when an order is placed, such as saving subscription details. This can be done using subscribers, which register handler methods to be triggered when an event is emitted. When an order is placed, the `order.placed` event is emitted.
2. Check daily for subscriptions that need renewal. This can be done using a scheduled job, which is a cron job that can be executed on a defined interval. Within that job, you can define your renewal logic.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/development/events/create-subscriber',
label: 'Create a Subscriber',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a subscriber in Medusa.',
}
},
{
type: 'link',
href: '/development/scheduled-jobs/create',
label: 'Create a Scheduled Job',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a scheduled job in Medusa.',
}
},
]} />
---
## Build a Storefront
Medusa provides a Next.js starter storefront that you can use with Medusa. Since you've customized your Medusa project, you'll need to either customize the existing Next.js storefront, or create a custom storefront.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/starters/nextjs-medusa-starter',
label: 'Option 1: Use Next.js Storefront',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Install the Next.js Storefront to customize it.',
}
},
{
type: 'link',
href: '/storefront/roadmap',
label: 'Option 2: Build Custom Storefront',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Find useful resources to build your own storefront.',
}
},
]} />
---
## Deploy Backend
Our documentation includes deployment guides for a basic Medusa backend. You should be able to follow it to deploy your customized backend, as well.
<DocCard item={{
type: 'link',
href: '/deployments/server',
label: 'Deploy Backend',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to deploy your subscription-based backend to different hosting providers.',
}
}} />
---
## Additional Development
You can find other resources for your development in the [Medusa Development section](../development/overview.mdx) of this documentation.