Bundle pages stay styled and functional when the app embed is off (e.g. on a draft theme). Listing screenshots captured from the dev store and rendered at 1600x900. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
29 lines
1.6 KiB
TypeScript
29 lines
1.6 KiB
TypeScript
// /apps/bundles/{handle} (app proxy): bundle page (F13, F14). Guests welcome; not running -> 404;
|
|
// renamed offer -> 301 to the current handle.
|
|
import type { LoaderFunctionArgs } from "react-router";
|
|
import { redirect } from "react-router";
|
|
import { authenticate } from "../shopify.server";
|
|
import db from "../db.server";
|
|
import { PROXY_CACHE, runningOffersForShop } from "../lib/proxy.server";
|
|
import { bundlePageLiquid, notFoundLiquid, proxyBase, selfContained } from "../lib/storefront.server";
|
|
|
|
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
|
const { liquid } = await authenticate.public.appProxy(request);
|
|
const url = new URL(request.url);
|
|
const shop = url.searchParams.get("shop") || "";
|
|
const base = proxyBase(url.searchParams.get("path_prefix"));
|
|
const handle = (params.handle || "").toLowerCase();
|
|
const locale = request.headers.get("accept-language")?.split(",")[0]?.split("-")[0] || null;
|
|
const data = await runningOffersForShop(shop, request.headers.get("x-shopify-country") || null);
|
|
if (!data) return liquid(notFoundLiquid(base), { status: 404 });
|
|
|
|
const offer = data.running.find((o) => o.handle === handle);
|
|
if (offer) return liquid(selfContained(bundlePageLiquid(offer, data.ctx, locale)), { headers: { "Cache-Control": PROXY_CACHE } });
|
|
|
|
const renamed = await db.offer.findFirst({ where: { shopId: data.shop.id, oldHandles: { has: handle } }, select: { id: true, handle: true } });
|
|
if (renamed && data.running.some((o) => o.id === renamed.id)) {
|
|
return redirect(`${base}/${renamed.handle}`, 301);
|
|
}
|
|
return liquid(notFoundLiquid(base), { status: 404 });
|
|
};
|