如何使用 Medusa 和 Next.js 构建视频游戏商店

2025-06-07

如何使用 Medusa 和 Next.js 构建视频游戏商店

Medusa是一个基于 Node.js 的开源电商平台。Medusa 允许开发者以最少的投入和良好的开发者体验创建可扩展且复杂的商业设置。它是 Shopify 的开源替代方案,拥有卓越的开发者体验和无限的自定义选项,适合希望扩展规模的商家。

Medusa 拥有丰富的电商功能,例如订单、换货、退货等等。这些功能让 Medusa 有别于其他无头商务 CMS。

本月初,Medusa 发起了一场黑客马拉松,为参与者提供赢取丰厚奖品的机会,例如免费礼品、绝佳的项目机会以及 1,500 美元的现金奖励。以下是您可以创建并参与黑客马拉松的项目示例。

在本教程中,您将学习如何使用 Medusa 的 Next.js 店面创建视频商店。您将与 Stripe 和 Algolia 进行集成。

您可以在此 GitHub 存储库中查看完整代码

图片描述

先决条件

在开始本教程之前,请确保您满足以下要求:

创建 Medusa 服务器

满足上述要求后,运行以下命令安装 Medusa CLI 工具:



yarn global add @medusajs/medusa-cli


Enter fullscreen mode Exit fullscreen mode

然后,使用以下命令创建 Medusa 应用程序:



yarn create medusa-app


Enter fullscreen mode Exit fullscreen mode

上述命令将提示您选择此应用程序的安装文件夹。输入gamestore作为项目文件夹名称,选择medusa-starter-default作为此项目的启动器,并选择Next.js Starter作为要安装的店面启动器。

您的选择应该类似于下面的屏幕截图:

图片描述

现在,等待 Medusa 创建运行应用程序所需的文件夹和文件。安装完成后,Medusa 将在该gamestore文件夹中创建三个主文件夹:adminbackendstorefront

接下来,打开三个不同的终端选项卡。将目录切换到这些文件夹,并使用以下命令启动应用程序的各个部分。同时在相应的终端中运行每个命令:



# Medusa server
cd gamestore/backend
yarn start

# Admin
cd gamestore/admin
yarn start

# Storefront
cd gamestore/storefront
yarn dev


Enter fullscreen mode Exit fullscreen mode

安装 Algolia 插件

Algolia 是一种搜索引擎服务,它使开发人员能够将诸如拼写错误容忍、推荐结果和快速响应等高级搜索功能集成到他们的网站中。

在安装插件之前,请按照此处的步骤获取您的 Algolia 应用程序 ID、仅搜索 API 密钥和管理 API 密钥* *

然后,通过在 Medusa 后端根文件夹中运行以下命令来安装 Algolia 插件:



yarn add medusa-plugin-algolia


Enter fullscreen mode Exit fullscreen mode

并将以下环境变量添加到您的 Medusa 服务器:



ALGOLIA_APP_ID=<YOUR_APP_ID>
ALGOLIA_ADMIN_API_KEY=<YOUR_ADMIN_API_KEY>


Enter fullscreen mode Exit fullscreen mode

<YOUR_APP_ID> 和 <YOUR_ADMIN_API_KEY> 分别是应用程序 ID 和管理 API 密钥。

最后,在 中将 medusa-config.js以下项添加到 plugins 数组中:



const plugins = [
  //...
  {
    resolve: `medusa-plugin-algolia`,
    options: {
      application_id: process.env.ALGOLIA_APP_ID,
      admin_api_key: process.env.ALGOLIA_ADMIN_API_KEY,
      settings: {
        products: {
          searchableAttributes: ["title", "description"],
          attributesToRetrieve: [
            "id",
            "title",
            "description",
            "handle",
            "thumbnail",
            "variants",
            "variant_sku",
            "options",
            "collection_title",
            "collection_handle",
            "images",
          ],
        },
      },
    },
  },
];


Enter fullscreen mode Exit fullscreen mode

是 searchableAttributes产品中可以搜索的属性,attributesToRetrieve是搜索结果中应返回的产品属性。

安装 Stripe 插件

Stripe 是一个经过测试且值得信赖的交易处理平台。Stripe 为您提供安全处理交易所需的所有技术组件,以及洞察销售情况所需的分析功能。

使用以下命令安装 Stripe 插件:



yarn add medusa-payment-stripe


Enter fullscreen mode Exit fullscreen mode

接下来,在文件中添加 Stripe 插件的配置backend/medusa-config.js



const plugins = [
//...
  resolve: `medusa-payment-stripe`,
    options: {
      api_key: STRIPE_API_KEY,
      webhook_secret: STRIPE_WEBHOOK_SECRET,
    },
   },
]


Enter fullscreen mode Exit fullscreen mode

最后,在文件中添加backend/.env您的api_keywebhook_secret键到STRIPE_API_KEYSTRIPE_WEBHOOK_SECRET环境变量中。



STRIPE_API_KEY=<YOUR STRIPE_API_KEY>
STRIPE_WEBHOOK_SECRET=<YOUR STRIPE_WEBHOOK_SECRET>


Enter fullscreen mode Exit fullscreen mode

安装文件服务插件(MinIO)

MinIO 是一个用 Go 编写的开源分布式对象存储服务器,适用于私有云基础设施并提供 S3 存储功能。

Medusa 使用文件服务插件来存储产品图片等文件。创建产品时,添加文件服务插件非常重要。您可以使用 MinIO、S3DigitalOcean Spaces

使用以下命令安装MinIO插件模块:



yarn add medusa-file-minio


Enter fullscreen mode Exit fullscreen mode

接下来,打开您的backend/.env文件并添加以下凭据:



MINIO_ENDPOINT=<ENDPOINT>
MINIO_BUCKET=<BUCKET>
MINIO_ACCESS_KEY=<ACCESS_KEY>
MINIO_SECRET_KEY=<SECRET_KEY>


Enter fullscreen mode Exit fullscreen mode

<ENDPOINT> 是您的 MinIO 服务器的 URL, <BUCKET> 是您的 MinIO 存储桶的名称,和 <ACCESS_KEY> 是 <SECRET_KEY> 您的访问密钥和密钥。

最后在文件中的插件数组中添加如下配置backend/medusa-config.js



const plugins = [
//...
  {
    resolve: `medusa-file-minio`,
    options: {
        endpoint: process.env.MINIO_ENDPOINT,
        bucket: process.env.MINIO_BUCKET,
        access_key_id: process.env.MINIO_ACCESS_KEY,
        secret_access_key: process.env.MINIO_SECRET_KEY,
    },
  },
]


Enter fullscreen mode Exit fullscreen mode

使用 Medusa Admin 添加产品

Medusa Admin 是一款连接到 Medusa 服务器的应用程序,用于管理应用程序中的数据。在这里,您将从 Medusa Admin 向商店添加一些产品。

当您的 Medusa 服务器正在运行时,如果 Medusa 管理员尚未运行,请运行它:



yarn start


Enter fullscreen mode Exit fullscreen mode

然后,导航到http://localhost:7000Medusa Admin。您将看到一个登录屏幕。

图片描述

Medusa 已为您的数据库植入了一个可供您登录的演示管理员账户。请使用以下凭证登录:

  • 电子邮件:admin@medusa-test.com
  • 密码:supersecret

登录后,您应该可以访问 Medusa 仪表板,您可以在其中管理您的应用程序内容(创建产品、管理订单等)。

图片描述

在产品页面上,点击“添加新产品”按钮,添加一些电子游戏产品。您可以添加任意数量的产品。

图片描述

自定义 Next.js 店面

现在我们已经在管理员中添加并创建了一些视频游戏,让我们自定义店面,使其看起来像游戏商店应用程序。

为此,找到storefront****目录并修改以下文件。

您可以在 Github上下载店面使用的图像

  • storefront/src/modules/home/components/featured-products/index.tsx使用下面的代码片段:


...
const FeaturedProducts = () => {
  ...
  return (
    <div className="py-12">
      <div className="content-container py-12">
        <div className="flex flex-col items-center text-center mb-16">
          <span className="text-base-regular text-gray-600 mb-6">
            Trending On Funplay
          </span>
          <p className="text-2xl-regular text-gray-900 max-w-lg mb-4">
            Top 4 games this week
          </p>
          <UnderlineLink href="/store">Start Playing Now</UnderlineLink>
        </div>
          ...
      </div>
    </div>
  )
}
..


Enter fullscreen mode Exit fullscreen mode

这会改变特色产品组件的标题以及部分文本,以匹配我们商店的视频游戏概念。

  • storefront/src/modules/home/components/hero/index.tsx


...
const Hero = () => {
  return (
    <div className="h-[90vh] w-full relative">
      <div className="text-white absolute inset-0 z-10 flex flex-col justify-center items-center text-center small:text-left small:justify-end small:items-start small:p-32">
        <h1 className="text-2xl-semi mb-4 drop-shadow-md shadow-black">
          The best games on the planet
        </h1>
        <p className="text-base-regular max-w-[32rem] mb-6 drop-shadow-md shadow-black">
          We have the best games for you.
        </p>
        <UnderlineLink href="/store">Start Playing Now</UnderlineLink>
      </div>
      <Image
        src="/4db11d22-7f83-482d-920d-f0033b1e6306.jpeg"
        layout="fill"
        loading="eager"
        priority={true}
        quality={90}
        objectFit="cover"
        alt="Photo by @thevoncomplex https://unsplash.com/@thevoncomplex"
        className="absolute inset-0"
        draggable="false"
      />
    </div>
  )
}

...


Enter fullscreen mode Exit fullscreen mode

这会改变商店英雄部分的文字和图像。

  • storefront/src/modules/layout/components/footer-cta/index.tsx


...
const FooterCTA = () => {
  return (
    <div className="bg-amber-100 w-full">
      <div className="content-container flex flex-col-reverse gap-y-8 small:flex-row small:items-center justify-between py-16 relative">
        <div>
          <h3 className="text-2xl-semi">Play 3D Games at afforadable rates </h3>
          <div className="mt-6">
            <UnderlineLink href="/store">Start Playing Now</UnderlineLink>
          </div>
        </div>

        <div className="relative w-full aspect-square small:w-[35%] small:aspect-[28/36]">
          <Image
            src="/photo-1553481187-be93c21490a9.jpeg"
            alt=""
            layout="fill"
            objectFit="cover"
            className="absolute inset-0"
          />
        </div>
      </div>
    </div>
  )
}

...


Enter fullscreen mode Exit fullscreen mode

这会改变页脚之前部分中的文本和图像。

  • storefront/src/modules/layout/components/footer-nav/index.tsx


...

const FooterNav = () => {
 ...

  return (
    <div className="content-container flex flex-col gap-y-8 pt-16 pb-8">
      <div className="flex flex-col gap-y-6 xsmall:flex-row items-start justify-between">
        <div>
          <Link href="/">
            <a className="text-xl-semi uppercase">Funplay</a>
          </Link>
        </div>
        <div className="text-small-regular grid grid-cols-2 gap-x-16">
          <div className="flex flex-col gap-y-2">
            <span className="text-base-semi">Games</span>
            ...
        </div>
      </div>
      <div className="flex flex-col-reverse gap-y-4 justify-center xsmall:items-center xsmall:flex-row xsmall:items-end xsmall:justify-between">
        <span className="text-xsmall-regular text-gray-500">
          © Copyright 2022 Funplay
        </span>
        <div className="min-w-[316px] flex xsmall:justify-end">
          <CountrySelect />
        </div>
      </div>
    </div>
  )
}

...


Enter fullscreen mode Exit fullscreen mode

这会改变店面页脚中的文本。

  • storefront/src/modules/store/components/index.tsx


//...
  return (
    <div>
      <div className="px-8 py-4  small:pr-0 small:pl-8 small:min-w-[250px]">
        <div className="flex gap-x-3 small:flex-col small:gap-y-3">
          <span className="text-base-semi">Games</span>
          {//...}
        </div>
      </div>
    </div>
  )
}

...


Enter fullscreen mode Exit fullscreen mode

这会改变商店页面中的文本。

  • storefront/src/pages/index.tsx


...

const Home: NextPageWithLayout = () => {
  return (
    <>
      <Head
        title="Home"
        description="Shop all available games only at the Funplay. Worldwide Shipping. Secure Payment."
      />
      <Hero />
      <FeaturedProducts />
    </>
  )
}

...


Enter fullscreen mode Exit fullscreen mode

这会改变店面的元数据。

测试店面

确保 Medusa 服务器仍在运行。然后,运行以下命令启动店面:



yarn run dev


Enter fullscreen mode Exit fullscreen mode

现在,导航http://localhost:8000至预览 Medusa 商店中的产品。

图片描述

然后点击导航栏****中的商店链接即可查看商店中的商品。

图片描述

添加 Algolia 集成

Algolia 集成已默认内置于 Next.js 商店中。您只需三个步骤即可使其运行。

首先,在文件中启用搜索功能store.config.json



{
  "features": {
    "search": true
  }
}



Enter fullscreen mode Exit fullscreen mode

然后,在文件中添加必要的环境变量.env.local

如果.env.local不可用,请确保重命名.env.template.env.local



NEXT_PUBLIC_SEARCH_APP_ID=<YOUR_APP_ID>
NEXT_PUBLIC_SEARCH_API_KEY=<YOUR_SEARCH_API_KEY>
NEXT_PUBLIC_SEARCH_INDEX_NAME=products


Enter fullscreen mode Exit fullscreen mode

<YOUR APP ID>分别是 Algolia 上的API 密钥页面<YOUR SEARCH API KEY>上的应用程序 ID 和仅搜索 API 密钥。

最后,将代码更改为 src/lib/search-client.ts 下面的代码片段:



import algoliasearch from "algoliasearch/lite"

const appId = process.env.NEXT_PUBLIC_SEARCH_APP_ID || "" // You should add this to your environment variables

const apiKey = process.env.NEXT_PUBLIC_SEARCH_API_KEY || "test_key"

export const searchClient = algoliasearch(appId, apiKey)

export const SEARCH_INDEX_NAME =
  process.env.NEXT_PUBLIC_INDEX_NAME || "products"



Enter fullscreen mode Exit fullscreen mode

如果您在 Medusa 服务器运行时运行 Next.js 店面,则通过单击导航栏中的搜索图标即可在店面中使用搜索功能。

添加 Stripe 集成

本教程的最后一步是集成 Stripe 支付,以允许客户在结账时支付订单。

为此,您需要按照以下步骤将Stripe添加到 Medusa Admin 中的区域:

  1. 导航至“设置” > “区域”
  2. 对于每个区域,单击右侧第一部分右上角的三个点。
  3. 单击下拉菜单中的“编辑区域详细信息”。
  4. 在提供商部分下,选择 Stripe。
  5. 单击“保存”。

然后storefront/env.local添加以下环境键:



NEXT_PUBLIC_STRIPE_KEY=<YOUR_PUBLISHABLE_KEY>


Enter fullscreen mode Exit fullscreen mode

<YOUR_PUBLISHABLE_KEY>您的 Stripe 可发布密钥在哪里?

测试条

重启你的 Next.js 店面,并确保 Medusa 服务器仍在运行。然后,尝试将一些商品添加到购物车并继续结账。

在结账时,您可以在付款部分使用 Stripe 支付订单。

图片描述

结论

在本教程中,您学习了如何使用Medusa构建视频游戏商店。无论您使用的是 Next.js 店面还是您自己的店面,您都可以使用 Medusa 的插件系统集成其他服务,例如 Stripe 和 Algolia。

要了解您可以使用 Medusa 做什么,请查看Medusa 的文档,了解有关不同集成、API 参考、用户指南等的指南。

如果您有与 Medusa 相关的任何问题或疑问,请随时通过Discord联系 Medusa 团队 

文章来源:https://dev.to/medusajs/how-to-build-a-video-game-store-with-medusa-and-nextjs-kem
PREV
美杜莎黑客马拉松报名:在 Hacktoberfest 期间赢取高达 1,500 美元的商品和奖品
NEXT
向五岁孩子解释“无头”