docs: added multi-region recipe (#4926)

* docs: added a multi-region recipe

* added other category to plugins list

* fix eslint errors

* fix broken link

* add link

* fix sidebar link
This commit is contained in:
Shahed Nasser
2023-08-31 20:38:06 +03:00
committed by GitHub
parent f9c064f98d
commit ddc882faac
6 changed files with 520 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
import DocCardList from '@theme/DocCardList';
# Other Plugins
<DocCardList />

View File

@@ -0,0 +1,143 @@
---
addHowToData: true
---
# IP Lookup (ipstack) Plugin
In this document, youll learn how to install the IP Lookup plugin on your Medusa backend.
## Overview
Location detection in a commerce store is essential for multi-region support. Medusa provides an IP Lookup plugin that integrates the backend with [ipstack](https://ipstack.com/) to allow you to detect a customers location and, ultimately, their region.
This guide explains how you can install and use this plugin.
---
## Prerequisites
### Medusa Backend
Before you follow this guide, you must have a Medusa backend installed. If not, you can follow the [quickstart guide](../../create-medusa-app.mdx) to learn how to do it.
### ipstack Account
You need an [ipstack account](https://ipstack.com/) before using this plugin. You can create a free account with ipstack on their website.
---
## Install Plugin
In the root directory of your Medusa backend, run the following command to install the IP Lookup plugin:
```bash npm2yarn
npm install medusa-plugin-ip-lookup
```
Then, add the following environment variable in `.env`:
```bash
IPSTACK_ACCESS_KEY=<YOUR_ACCESS_KEY>
```
Where `<YOUR_ACCESS_KEY>` is your ipstack accounts access key. Its available in your ipstack dashboard.
Finally, add the IP lookup plugin into the plugins array exported as part of the Medusa configuration in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// other plugins...
{
resolve: `medusa-plugin-ip-lookup`,
options: {
access_token: process.env.IPSTACK_ACCESS_KEY,
},
},
]
```
---
## Test the Plugin
The plugin provides two resources: the `IpLookupService` and the `preCartCreation` middleware.
:::note
Due to how Express resolves the current IP when accessing your website from `localhost`, you wont be able to test the plugin locally. You can either use tools like ngrok to expose the `9000` port to be accessed publicly, or you have to test it on a deployed backend.
:::
### IpLookupService
The `IpLookupService` can be used in other services, endpoints, or resources to get the users location by their IP address. It has only one method `lookupIp` that accepts the IP address as a parameter, sends a request to ipstacks API, and returns the retrieved result.
For example, you can use the `IpLookupService` in a custom endpoint and return the users region:
:::tip
You can learn more about creating an endpoint [here](../../development/endpoints/create.mdx).
:::
```ts title=src/api/index.ts
import { Request, Response, Router } from "express"
export default (rootDirectory: string): Router | Router[] => {
const router = Router()
// ...
router.get(
"/store/customer-region",
async (req: Request, res: Response) => {
const ipLookupService = req.scope.resolve(
"ipLookupService"
)
const regionService = req.scope.resolve<RegionService>(
"regionService"
)
const ip = req.headers["x-forwarded-for"] ||
req.socket.remoteAddress
const { data } = await ipLookupService.lookupIp(ip)
if (!data.country_code) {
throw new Error ("Couldn't detect country code.")
}
const region = await regionService
.retrieveByCountryCode(data.country_code)
res.json({
region,
})
}
)
}
```
### preCartCreation
The `preCartCreation` middleware can be added as a middleware to any route to attach the region ID to that route based on the users location. For example, you can use it on the Create Cart endpoint to ensure that the users correct region is attached to the cart.
For example, you can attach it to all `/store` routes to ensure the customers region is always detected:
<!-- eslint-disable @typescript-eslint/no-var-requires -->
```ts title=src/api/index.ts
import { Router } from "express"
const { preCartCreation } = require(
"medusa-plugin-ip-lookup/api/medusa-middleware"
).default
export default (
rootDirectory: string
): Router | Router[] => {
const router = Router()
// ...
router.use("/store", preCartCreation)
return router
}
```

View File

@@ -74,6 +74,15 @@ Interested in creating a plugin? Learn more in the [Create Plugin documentation]
description: 'Check out official File Service plugins.'
}
},
{
type: 'link',
href: '/plugins/other',
label: 'Other Plugins',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out other official plugins.'
}
},
]} />
<!-- vale docs.Acronyms = YES -->

View File

@@ -72,7 +72,7 @@ Follow this guide if you want to build a B2B/Wholesale store.
href: '/recipes/b2b',
label: 'Build B2B Store',
customProps: {
icon: Icons['credit-card-solid'],
icon: Icons['building-solid'],
description: 'Learn how you can build a B2B store in Medusa.'
}
}} />
@@ -87,6 +87,30 @@ Follow this guide if you want to build a B2B/Wholesale store.
---
## Recipe: Build Multi-Region Store
Learn how you can build a multi-region store with Medusa.
<DocCard item={{
type: 'link',
href: '/recipes/multi-region',
label: 'Build Multi-Region Store',
customProps: {
icon: Icons['globe-europe-solid'],
description: 'Learn how you can build a multi-region store 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?"
showLongForm={false}
/>
---
<!-- vale docs.HeadingPunctuation = NO -->
## Can't find your path?

View File

@@ -0,0 +1,309 @@
---
addHowToData: true
---
import DocCardList from '@theme/DocCardList';
import Icons from '@theme/Icon';
# Multi-Regional Store
This document guides you through the different features and resources available in Medusa to create a multi-regional store.
## Overview
A multi-regional store allows merchants to sell across different countries. This includes supporting each countrys tax rules, currency, available shipping and payment options, and more.
Medusa provides the necessary features to create a multi-regional store out of the box. This recipe explains how you can benefit from Medusas features to create a multi-regional store.
---
## Multi-Region Setup
With Medusa, you can create an unlimited number of regions in your store. Each region can have its own configurations. These configurations can be managed either through the Medusa admin or the Admin REST APIs.
### Currency
Merchants can specify the currency of each region. Multiple regions can have the same currency, but a region can have only one currency.
This affects what currency are prices shown to the customer in a region. As explained later, this also affects what prices are shown to the customer as well in a region.
### Tax rates and providers
Merchants can define for each region a default tax rate and tax rates for specific conditions (for example, for a specific set of products). Each region can also have a different tax provider that calculates the taxes. You can use Medusas default tax provider, or create your own tax provider.
During checkout, the taxes are calculated based on the customers region and its taxes configurations and rates.
<DocCardList colSize={4} items={[
{
type: 'link',
href: '/user-guide/taxes/manage',
label: 'Manage Taxes in Medusa Admin',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage taxes in Medusa Admin.',
}
},
{
type: 'link',
href: '/modules/taxes/admin/manage-tax-settings',
label: 'Manage Taxes Using Admin APIs',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to manage tax settings using the Admin APIs.',
}
},
{
type: 'link',
href: '/modules/taxes/backend/create-tax-provider',
label: 'Create Tax Provider',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a tax provider.',
}
},
]} />
### Payment and Fulfillment Providers
Merchants can choose which payment and fulfillment providers are available in which regions. For example, a region may have Stripe enabled as a payment provider, while another may have PayPal enabled instead.
This affects what payment and shipping methods are shown to the customer during checkout. Customers can only use the methods enabled in their region.
Medusa provides official plugins for payment and fulfillment providers. You can also create your own providers.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/user-guide/regions/providers',
label: 'Manage Providers in Medusa Admin',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage providers in Medusa Admin.',
}
},
{
type: 'link',
href: '/plugins/payment',
label: 'Available Payment Plugins',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Check out available payment plugins',
}
},
{
type: 'link',
href: '/modules/carts-and-checkout/backend/add-payment-provider',
label: 'Create Payment Provider',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a payment provider.',
}
},
{
type: 'link',
href: '/modules/carts-and-checkout/backend/add-fulfillment-provider',
label: 'Create Fulfillment Provider',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a fulfillment provider.',
}
},
]} />
---
## Prices Per Region and Currency
When a merchant sets the price of a product in Medusa, they can specify the price per currency and per region. Merchants can also benefit from this pricing mechanism when adding sales or overriding prices for specific conditions using the [Price Lists feature](../modules/price-lists/overview.mdx).
Then, customers see the price of a product based on the region theyre in and the regions currency, and whether any special pricing applies to their case. Medusa has a pricing strategy (which you can override) to show the customer the best price based on their context.
Using the [tax-inclusive beta feature](../beta.md#tax-inclusive-pricing), merchants can also specify prices that include taxes per currency and region. Medusa then takes care of calculating the tax amount applied to a line item in the cart based on the regions tax configurations.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/user-guide/products/manage#edit-product-prices-with-bulk-editor',
label: 'Setting Product Prices in Medusa Admin',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to set a product prices in Medusa Admin.',
}
},
{
type: 'link',
href: '/plugins/payment',
label: 'Display Product Price in Storefront',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to display the correct product price in a storefront.',
}
},
]} />
---
## Product Availability Per Region
In a multi-regional setup, you may have products that should only be available in certain regions. Using the Sales Channels feature, you can control the availability of products within different channels.
Sales channels arent directly associated with regions by default, but you can create a custom relation between the `SalesChannel` entity and the `Region` entity. Alternatively, you can utilize the `metadata` attribute of each entity, which is an attribute that can be used to add custom data, to set the ID of the associated sales channel or region for each entity.
Then, when a customer is viewing the products from a region, only the products available in the regions associated sales channel are retrieved and shown to the customer.
This also allows you to create or deploy different storefronts for different regions, if necessary. Each storefront only shows the products available in a region and its sales channel.
It should also be noted that a cart is associated with a region and a sales channel. So, customers can only buy a product if it belongs to the same sales channel as the cart.
<DocCardList colSize={4} items={[
{
type: 'link',
href: '/modules/sales-channels/overview',
label: 'Sales Channels Overview',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn about the sales channel feature in Medusa.',
}
},
{
type: 'link',
href: '/development/entities/extend-entity',
label: 'Extend Entities',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to extend entities in the Medusa backend.',
}
},
{
type: 'link',
href: '/modules/sales-channels/storefront/use-sales-channels',
label: 'Show Products by Sales Channel',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to show products by a sales channel in the storefront.',
}
},
]} />
---
## Multi-Warehouse Support
Medusa provides Multi-warehouse features that allow you to manage your inventory across different locations. Merchants can then control which location an item in an order is fulfilled from, allowing them to keep a correct inventory count across locations and selling channels.
In a multi-regional setup, this can allow you to manage your inventory through Medusa across the different regions you serve. Your products inventory and availability arent bound to a single stock location, and customers are always shown accurate inventory information based on the location associated with their sales channel.
<DocCardList colSize={4} items={[
{
type: 'link',
href: '/modules/multiwarehouse/overview',
label: 'Multi-warehouse Overview',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn about the Multi-warehouse feature in Medusa.',
}
},
{
type: 'link',
href: '/user-guide/multiwarehouse/locations',
label: 'Manage Stock Locations',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage stock locations in the Medusa admin.',
}
},
{
type: 'link',
href: '/user-guide/multiwarehouse/inventory',
label: 'Manage Inventory',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage inventory in the Medusa admin.',
}
},
]} />
---
## Multi-Lingual Setup with Third-Party CMS
Medusa can be integrated with any third-party services, including Content Management Systems (CMS). With a third-party CMS, you can benefit from rich CMS features, including managing your content in multiple languages. This allows you to cater to customers different languages in the regions you serve.
Medusa provides an official Contentful plugin and a community Strapi plugin. You can also create your own CMS plugin that integrates with your preferred CMS platform to provide multi-lingual features.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/plugins/cms',
label: 'CMS Plugins',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn about available CMS plugins for the Medusa backend.',
}
},
{
type: 'link',
href: '/development/plugins/create',
label: 'How to Create a Plugin',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a plugin for the Medusa backend.',
}
},
]} />
---
## Automatic Location Detection
When you sell across regions, its important to be able to detect the customers region and provide them with the products, prices, and content relevant to them without requiring actions from their side.
Medusa provides an IP Lookup plugin that allows you to detect a customers location and, ultimately, their region using [ipstack](https://ipstack.com/). You can also create a plugin that detects the location through a different logic.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/plugins/other/ip-lookup',
label: 'IP Lookup Plugin',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to use the IP Lookup plugin in your Medusa backend.',
}
},
{
type: 'link',
href: '/development/plugins/create',
label: 'How to Create a Plugin',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to create a plugin for the Medusa backend.',
}
},
]} />
---
## Additional Features and Development Resources
Medusa provides other essential commerce features and development resources to help you build your multi-region store.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/overview',
label: 'Commerce Modules',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn about the available commerce features and modules in Medusa.',
}
},
{
type: 'link',
href: '/development/overview',
label: 'Medusa Development',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to customize your Medusa backend for your use case.',
}
},
]} />

View File

@@ -62,6 +62,11 @@ module.exports = {
id: "recipes/b2b",
label: "B2B / Wholesale",
},
{
type: "doc",
id: "recipes/multi-region",
label: "Multi-Region Store",
},
],
},
{
@@ -2285,6 +2290,30 @@ module.exports = {
},
],
},
{
type: "category",
label: "Other",
collapsible: false,
link: {
type: "doc",
id: "plugins/other/index",
},
customProps: {
sidebar_is_group_headline: true,
},
items: [
{
type: "doc",
id: "plugins/other/ip-lookup",
label: "IP Lookup",
customProps: {
iconName: "bolt-solid",
description:
"Learn how to integrate ipstack to access the user's region.",
},
},
],
},
],
],
userGuideSidebar: [