首页 > 解决方案 > Shopify Storefront 上的嵌入式自定义 NextJS 应用程序更改资产文件路径

问题描述

我想知道是否有人可以帮助我。我在 Heroku 上构建了一个自定义 NextJS 应用程序,打算使用 Shopify 的应用程序代理嵌入到我的 Shopify 店面中。它大部分都在工作,所以当我转到 Shopify 商店中的代理 URL 时,它会显示我的应用程序,但是所有 CSS 和 JS 文件路径都已更改为我的 Shopify URL,而不是保留为我的 Heroku 应用程序 URL。

我见过其他人也有同样的问题:https ://community.shopify.com/c/Shopify-APIs-SDKs/App-Proxy-Sending-index-html-throws-404-on-the-JS-and -CSS文件/td-p/586595

但是,当我尝试实施此解决方案时,它会不断破坏应用程序。我对 Node.js/Next.js 比较陌生,所以当我还在学习时,我主要依赖文档来设置或解决此类问题。但是,我找不到任何针对此问题的教程或文档。

是否有人能够建议我在 server.js 中需要做什么,以便在从代理 URL 查看时从我的 Heroku 应用程序 URL 而不是 Shopify URL 中提取“/_next/static/...”文件? 我在下面包含了我的 server.js 文件的内容。

require('isomorphic-fetch');
const dotenv = require('dotenv');
const Koa = require('koa');
const next = require('next');
const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
const { verifyRequest } = require('@shopify/koa-shopify-auth');
const { default: Shopify, ApiVersion } = require('@shopify/shopify-api');
const Router = require('koa-router');

dotenv.config();

Shopify.Context.initialize({
  API_KEY: process.env.SHOPIFY_API_KEY,
  API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
  SCOPES: process.env.SHOPIFY_API_SCOPES.split(","),
  HOST_NAME: process.env.SHOPIFY_APP_URL.replace(/https:\/\//, ""),
  API_VERSION: ApiVersion.October20,
  IS_EMBEDDED_APP: true,
  SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const ACTIVE_SHOPIFY_SHOPS = {};

app.prepare().then(() => {
  const server = new Koa();
  const router = new Router();
  server.keys = [Shopify.Context.API_SECRET_KEY];
  server.use(
    createShopifyAuth({
        apiKey: process.env.SHOPIFY_API_KEY,
        secret: process.env.SHOPIFY_API_SECRET,
        scopes: ["read_products"],
      afterAuth(ctx) {
        const { shop, scope } = ctx.state.shopify;
        ACTIVE_SHOPIFY_SHOPS[shop] = scope;
        ctx.redirect(`/?shop=${shop}`);
      },
    }),
  );

  const handleRequest = async (ctx) => {
      console.log('ctx.req.url', ctx.req.host);
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
  };

  router.get("/", async (ctx) => {
    const shop = ctx.query.shop;

    ACTIVE_SHOPIFY_SHOPS[shop] = ctx.query.shop;
    if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
        ctx.redirect(`/auth?shop=${shop}`);
    } else {
        await handleRequest(ctx);
    }
  });

  router.get("/_next/*", handleRequest);
  router.get("(.*)", verifyRequest(), handleRequest);

  server.use(router.allowedMethods());
  server.use(router.routes());

  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});

非常感谢

标签: node.jsnext.jsshopifykoashopify-app

解决方案


一个简单的解决方法是assetPrefix在 next.config.js 上使用。

assetPrefix自动为 /_next/ 路径添加前缀,因此资产使用绝对 URL 引用。

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  assetPrefix: isProd ? 'https://yourappdomain.com' : '',
}

https://nextjs.org/docs/api-reference/next.config.js/cdn-support-with-asset-prefix


推荐阅读