diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b3d330..6a0aa446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # @shopify/shopify-app-template-remix -## 2024.11.26 +## 2024.12.04 +- [#891](https://github.com/Shopify/shopify-app-template-remix/pull/891) Enable remix future flags. +- +## 2024.11.26 - [888](https://github.com/Shopify/shopify-app-template-remix/pull/888) Update restResources version to 2024-10 + ## 2024.11.06 - [881](https://github.com/Shopify/shopify-app-template-remix/pull/881) Update to the productCreate mutation to use the new ProductCreateInput type diff --git a/README.md b/README.md index 1ffdc8fa..fd1a376e 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ export async function loader({ request }) { }, } = await response.json(); - return json(nodes); + return nodes; } ``` diff --git a/app/entry.server.jsx b/app/entry.server.jsx index 10e8d37d..77a0c2aa 100644 --- a/app/entry.server.jsx +++ b/app/entry.server.jsx @@ -5,7 +5,7 @@ import { createReadableStreamFromReadable } from "@remix-run/node"; import { isbot } from "isbot"; import { addDocumentResponseHeaders } from "./shopify.server"; -const ABORT_DELAY = 5000; +export const streamTimeout = 5000; export default async function handleRequest( request, @@ -19,11 +19,7 @@ export default async function handleRequest( return new Promise((resolve, reject) => { const { pipe, abort } = renderToPipeableStream( - , + , { [callbackName]: () => { const body = new PassThrough(); @@ -48,6 +44,8 @@ export default async function handleRequest( }, ); - setTimeout(abort, ABORT_DELAY); + // Automatically timeout the React renderer after 6 seconds, which ensures + // React has enough time to flush down the rejected boundary contents + setTimeout(abort, streamTimeout + 1000); }); } diff --git a/app/routes.js b/app/routes.js new file mode 100644 index 00000000..83892841 --- /dev/null +++ b/app/routes.js @@ -0,0 +1,3 @@ +import { flatRoutes } from "@remix-run/fs-routes"; + +export default flatRoutes(); diff --git a/app/routes/_index/route.jsx b/app/routes/_index/route.jsx index b319dbab..e86793f9 100644 --- a/app/routes/_index/route.jsx +++ b/app/routes/_index/route.jsx @@ -1,4 +1,4 @@ -import { json, redirect } from "@remix-run/node"; +import { redirect } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { login } from "../../shopify.server"; import styles from "./styles.module.css"; @@ -10,7 +10,7 @@ export const loader = async ({ request }) => { throw redirect(`/app?${url.searchParams.toString()}`); } - return json({ showForm: Boolean(login) }); + return { showForm: Boolean(login) }; }; export default function App() { diff --git a/app/routes/app._index.jsx b/app/routes/app._index.jsx index dae489ee..9854a9af 100644 --- a/app/routes/app._index.jsx +++ b/app/routes/app._index.jsx @@ -1,5 +1,4 @@ import { useEffect } from "react"; -import { json } from "@remix-run/node"; import { useFetcher } from "@remix-run/react"; import { Page, @@ -81,10 +80,10 @@ export const action = async ({ request }) => { ); const variantResponseJson = await variantResponse.json(); - return json({ + return { product: responseJson.data.productCreate.product, variant: variantResponseJson.data.productVariantsBulkUpdate.productVariants, - }); + }; }; export default function Index() { diff --git a/app/routes/app.jsx b/app/routes/app.jsx index 65293cdd..4bf86906 100644 --- a/app/routes/app.jsx +++ b/app/routes/app.jsx @@ -1,4 +1,3 @@ -import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData, useRouteError } from "@remix-run/react"; import { boundary } from "@shopify/shopify-app-remix/server"; import { AppProvider } from "@shopify/shopify-app-remix/react"; @@ -11,7 +10,7 @@ export const links = () => [{ rel: "stylesheet", href: polarisStyles }]; export const loader = async ({ request }) => { await authenticate.admin(request); - return json({ apiKey: process.env.SHOPIFY_API_KEY || "" }); + return { apiKey: process.env.SHOPIFY_API_KEY || "" }; }; export default function App() { diff --git a/app/routes/auth.login/route.jsx b/app/routes/auth.login/route.jsx index 73b477ae..5e19ff71 100644 --- a/app/routes/auth.login/route.jsx +++ b/app/routes/auth.login/route.jsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import { json } from "@remix-run/node"; import { Form, useActionData, useLoaderData } from "@remix-run/react"; import { AppProvider as PolarisAppProvider, @@ -20,15 +19,15 @@ export const links = () => [{ rel: "stylesheet", href: polarisStyles }]; export const loader = async ({ request }) => { const errors = loginErrorMessage(await login(request)); - return json({ errors, polarisTranslations }); + return { errors, polarisTranslations }; }; export const action = async ({ request }) => { const errors = loginErrorMessage(await login(request)); - return json({ + return { errors, - }); + }; }; export default function Auth() { diff --git a/package.json b/package.json index 7d2409da..20f843da 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,8 @@ }, "devDependencies": { "@remix-run/eslint-config": "^2.7.1", + "@remix-run/fs-routes": "^2.15.0", + "@remix-run/route-config": "^2.15.0", "@shopify/api-codegen-preset": "^1.1.1", "@types/eslint": "^8.40.0", "@types/node": "^22.2.0", diff --git a/vite.config.js b/vite.config.js index 5003fa44..204a574d 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,7 +1,10 @@ import { vitePlugin as remix } from "@remix-run/dev"; +import { installGlobals } from "@remix-run/node"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; +installGlobals({ nativeFetch: true }); + // Related: https://github.com/remix-run/remix/issues/2835#issuecomment-1144102176 // Replace the HOST env var with SHOPIFY_APP_URL so that it doesn't break the remix server. The CLI will eventually // stop passing in HOST, so we can remove this workaround after the next major release. @@ -46,6 +49,14 @@ export default defineConfig({ plugins: [ remix({ ignoredRouteFiles: ["**/.*"], + future: { + v3_fetcherPersist: true, + v3_relativeSplatPath: true, + v3_throwAbortReason: true, + v3_lazyRouteDiscovery: true, + v3_singleFetch: true, + v3_routeConfig: true, + }, }), tsconfigPaths(), ],