diff --git a/.changeset/layout-error-boundary.md b/.changeset/layout-error-boundary.md deleted file mode 100644 index 09213d3ce10..00000000000 --- a/.changeset/layout-error-boundary.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/react": patch ---- - -Fix the default root `ErrorBoundary` component so it leverages the user-provided `Layout` component diff --git a/.changeset/layout-hydrate-fallback.md b/.changeset/layout-hydrate-fallback.md deleted file mode 100644 index 45f78c23716..00000000000 --- a/.changeset/layout-hydrate-fallback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/react": patch ---- - -Fix the default root `HydrateFallback` component so it leverages any user-provided `Layout` component diff --git a/.changeset/many-grapes-confess.md b/.changeset/many-grapes-confess.md deleted file mode 100644 index 17922aa9e2a..00000000000 --- a/.changeset/many-grapes-confess.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"remix": patch -"@remix-run/dev": patch ---- - -fix: mark Layout as browser safe route export diff --git a/.changeset/quick-experts-enjoy.md b/.changeset/quick-experts-enjoy.md deleted file mode 100644 index 211a848edac..00000000000 --- a/.changeset/quick-experts-enjoy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/dev": patch ---- - -Vite: Silence build warnings when dependencies include "use client" directives diff --git a/.changeset/shy-fireants-listen.md b/.changeset/shy-fireants-listen.md deleted file mode 100644 index b582244c631..00000000000 --- a/.changeset/shy-fireants-listen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/dev": minor ---- - -Pass resolved `viteConfig` to Remix Vite plugin's `buildEnd` hook diff --git a/.changeset/silver-years-roll.md b/.changeset/silver-years-roll.md deleted file mode 100644 index 1fa55b7570c..00000000000 --- a/.changeset/silver-years-roll.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/dev": patch ---- - -Vite: Fix `serverBundles` issue where multiple browser manifests are generated diff --git a/.changeset/tender-keys-develop.md b/.changeset/tender-keys-develop.md deleted file mode 100644 index 02968274fc5..00000000000 --- a/.changeset/tender-keys-develop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/dev": patch ---- - -Support custom Vite `build.assetsDir` option diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 068e6623a36..246dece0607 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -20,7 +20,7 @@ body: If you'd rather open a GitHub issue, here are other ways to share a reproduction (ordered from most helpful to least): - - 🥇 Link to a [StackBlitz](https://stackblitz.com/?starters=fullstack) environment + - 🥇 Link to a [StackBlitz](https://remix.new) environment - 🥈 Link to a GitHub repository - 🥉 Description of project including template, `remix.config.js`, `package.json` scripts, etc. diff --git a/CHANGELOG.md b/CHANGELOG.md index 243e9b396dd..1731bb8669f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,83 +13,88 @@ We manage release notes in this file instead of the paginated Github Releases Pa Table of Contents - [Remix Releases](#remix-releases) - - [2.7.2](#272) + - [v2.8.0](#v280) + - [Minor Changes](#minor-changes) - [Patch Changes](#patch-changes) - - [2.7.1](#271) + - [Updated Dependencies](#updated-dependencies) + - [Changes by Package](#changes-by-package) + - [2.7.2](#272) - [Patch Changes](#patch-changes-1) + - [2.7.1](#271) + - [Patch Changes](#patch-changes-2) - [v2.7.0](#v270) - [What's Changed](#whats-changed) - [Stabilized Vite Plugin](#stabilized-vite-plugin) - [New `Layout` Export](#new-layout-export) - [Basename support](#basename-support) - [Cloudflare Proxy as a Vite Plugin](#cloudflare-proxy-as-a-vite-plugin) - - [Minor Changes](#minor-changes) - - [Patch Changes](#patch-changes-2) - - [Updated Dependencies](#updated-dependencies) - - [Changes by Package](#changes-by-package) - - [v2.6.0](#v260) - - [What's Changed](#whats-changed-1) - - [Unstable Vite Plugin updates](#unstable-vite-plugin-updates) - [Minor Changes](#minor-changes-1) - [Patch Changes](#patch-changes-3) - [Updated Dependencies](#updated-dependencies-1) - [Changes by Package](#changes-by-package-1) - - [v2.5.1](#v251) + - [v2.6.0](#v260) + - [What's Changed](#whats-changed-1) + - [Unstable Vite Plugin updates](#unstable-vite-plugin-updates) + - [Minor Changes](#minor-changes-2) - [Patch Changes](#patch-changes-4) - [Updated Dependencies](#updated-dependencies-2) - [Changes by Package](#changes-by-package-2) + - [v2.5.1](#v251) + - [Patch Changes](#patch-changes-5) + - [Updated Dependencies](#updated-dependencies-3) + - [Changes by Package](#changes-by-package-3) - [v2.5.0](#v250) - [What's Changed](#whats-changed-2) - [SPA Mode (unstable)](#spa-mode-unstable) - [Server Bundles (unstable)](#server-bundles-unstable) - - [Minor Changes](#minor-changes-2) - - [Patch Changes](#patch-changes-5) - - [Updated Dependencies](#updated-dependencies-3) - - [Changes by Package](#changes-by-package-3) - - [v2.4.1](#v241) + - [Minor Changes](#minor-changes-3) - [Patch Changes](#patch-changes-6) - [Updated Dependencies](#updated-dependencies-4) - [Changes by Package](#changes-by-package-4) + - [v2.4.1](#v241) + - [Patch Changes](#patch-changes-7) + - [Updated Dependencies](#updated-dependencies-5) + - [Changes by Package](#changes-by-package-5) - [v2.4.0](#v240) - [What's Changed](#whats-changed-3) - [Client Data](#client-data) - [`future.v3_relativeSplatPath`](#futurev3_relativesplatpath) - [Vite Updates (Unstable)](#vite-updates-unstable) - - [Minor Changes](#minor-changes-3) - - [Patch Changes](#patch-changes-7) - - [Updated Dependencies](#updated-dependencies-5) - - [Changes by Package](#changes-by-package-5) - - [v2.3.1](#v231) + - [Minor Changes](#minor-changes-4) - [Patch Changes](#patch-changes-8) - [Updated Dependencies](#updated-dependencies-6) - [Changes by Package](#changes-by-package-6) + - [v2.3.1](#v231) + - [Patch Changes](#patch-changes-9) + - [Updated Dependencies](#updated-dependencies-7) + - [Changes by Package](#changes-by-package-7) - [v2.3.0](#v230) - [What's Changed](#whats-changed-4) - [Stabilized `useBlocker`](#stabilized-useblocker) - [`unstable_flushSync` API](#unstable_flushsync-api) - - [Minor Changes](#minor-changes-4) - - [Patch Changes](#patch-changes-9) - - [Updated Dependencies](#updated-dependencies-7) - - [Changes by Package](#changes-by-package-7) + - [Minor Changes](#minor-changes-5) + - [Patch Changes](#patch-changes-10) + - [Updated Dependencies](#updated-dependencies-8) + - [Changes by Package](#changes-by-package-8) - [v2.2.0](#v220) - [What's Changed](#whats-changed-5) - [Vite!](#vite) - [New Fetcher APIs](#new-fetcher-apis) - [Persistence Future Flag](#persistence-future-flag) - - [Minor Changes](#minor-changes-5) - - [Patch Changes](#patch-changes-10) - - [Updated Dependencies](#updated-dependencies-8) - - [Changes by Package](#changes-by-package-8) - - [v2.1.0](#v210) - - [What's Changed](#whats-changed-6) - - [View Transitions](#view-transitions) - - [Stable `createRemixStub`](#stable-createremixstub) - [Minor Changes](#minor-changes-6) - [Patch Changes](#patch-changes-11) - [Updated Dependencies](#updated-dependencies-9) - [Changes by Package](#changes-by-package-9) - - [v2.0.1](#v201) + - [v2.1.0](#v210) + - [What's Changed](#whats-changed-6) + - [View Transitions](#view-transitions) + - [Stable `createRemixStub`](#stable-createremixstub) + - [Minor Changes](#minor-changes-7) - [Patch Changes](#patch-changes-12) + - [Updated Dependencies](#updated-dependencies-10) + - [Changes by Package](#changes-by-package-10) + - [v2.0.1](#v201) + - [Patch Changes](#patch-changes-13) - [Changes by Package 🔗](#changes-by-package-) - [v2.0.0](#v200) - [Breaking Changes](#breaking-changes) @@ -101,8 +106,8 @@ We manage release notes in this file instead of the paginated Github Releases Pa - [Breaking Type Changes](#breaking-type-changes) - [New Features](#new-features) - [Other Notable Changes](#other-notable-changes) - - [Updated Dependencies](#updated-dependencies-10) - - [Changes by Package](#changes-by-package-10) + - [Updated Dependencies](#updated-dependencies-11) + - [Changes by Package](#changes-by-package-11) @@ -150,13 +155,55 @@ Date: YYYY-MM-DD --> +## v2.8.0 + +Date: 2024-02-28 + +### Minor Changes + +- `@remix-run/dev` - Vite: Pass resolved `viteConfig` to Remix Vite plugin's `buildEnd` hook ([#8885](https://github.com/remix-run/remix/pull/8885)) + +### Patch Changes + +- `@remix-run/dev` - Mark `Layout` as browser safe route export in `esbuild` compiler ([#8842](https://github.com/remix-run/remix/pull/8842)) +- `@remix-run/dev` - Vite: Silence build warnings when dependencies include `"use client"` directives ([#8897](https://github.com/remix-run/remix/pull/8897)) +- `@remix-run/dev` - Vite: Fix `serverBundles` issue where multiple browser manifests are generated ([#8864](https://github.com/remix-run/remix/pull/8864)) +- `@remix-run/dev` - Vite: Support custom `build.assetsDir` option ([#8843](https://github.com/remix-run/remix/pull/8843)) +- `@remix-run/react` - Fix the default root `ErrorBoundary` component so it leverages the user-provided `Layout` component ([#8859](https://github.com/remix-run/remix/pull/8859)) +- `@remix-run/react` - Fix the default root `HydrateFallback` component so it leverages any user-provided `Layout` component ([#8892](https://github.com/remix-run/remix/pull/8892)) + +### Updated Dependencies + +- [`react-router-dom@6.22.2`](https://github.com/remix-run/react-router/releases/tag/react-router%406.22.2) +- [`@remix-run/router@1.15.2`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1152) + +### Changes by Package + +- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/create-remix/CHANGELOG.md#280) +- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-architect/CHANGELOG.md#280) +- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-cloudflare/CHANGELOG.md#280) +- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-cloudflare-pages/CHANGELOG.md#280) +- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-cloudflare-workers/CHANGELOG.md#280) +- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-css-bundle/CHANGELOG.md#280) +- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-deno/CHANGELOG.md#280) +- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-dev/CHANGELOG.md#280) +- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-eslint-config/CHANGELOG.md#280) +- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-express/CHANGELOG.md#280) +- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-node/CHANGELOG.md#280) +- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-react/CHANGELOG.md#280) +- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-serve/CHANGELOG.md#280) +- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-server-runtime/CHANGELOG.md#280) +- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-testing/CHANGELOG.md#280) + +**Full Changelog**: [`v2.7.2...v2.8.0`](https://github.com/remix-run/remix/compare/remix@2.7.2...remix@2.8.0) + ## 2.7.2 Date: 2024-02-21 ### Patch Changes -- Vite: Fix error when building projects with `.css?url` imports ([#8829](https://github.com/remix-run/remix/pull/8829)) +- `@remix-run/dev` - Vite: Fix error when building projects with `.css?url` imports ([#8829](https://github.com/remix-run/remix/pull/8829)) ## 2.7.1 @@ -164,8 +211,7 @@ Date: 2024-02-20 ### Patch Changes -- Fix breaking change for `@remix-run/cloudflare-pages` ([#8819](https://github.com/remix-run/remix/pull/8819)) - - Restore Cloudflare event context fields in `getLoadContext` argument for backwards compatibility. +- `@remix-run/cloudflare-pages` - Fix breaking change and restore Cloudflare event context fields in `getLoadContext` argument for backwards compatibility ([#8819](https://github.com/remix-run/remix/pull/8819)) ## v2.7.0 diff --git a/contributors.yml b/contributors.yml index 6201abf7565..911c1eba923 100644 --- a/contributors.yml +++ b/contributors.yml @@ -12,6 +12,7 @@ - ahmedeldessouki - ahuth - aiji42 +- ainoya - airjp73 - airondumael - aissa-bouguern @@ -132,6 +133,7 @@ - Deanmv - defjosiah - denissb +- depsimon - derekr - derenge - devcamke @@ -316,6 +318,7 @@ - juwiragiye - jveldridge - jvnm-dev +- jwaltz - jwnx - kalch - kamtugeza @@ -594,6 +597,7 @@ - tjefferson08 - tmcw - tombiju +- tombohub - tombyrer - tomer-yechiel - TomerAberbach @@ -601,6 +605,7 @@ - toufiqnuur - toyozaki - TrySound +- ttsirkia - turkerdev - tvanantwerp - twhitbeck @@ -642,6 +647,7 @@ - yauri-io - yesmeck - yomeshgupta +- yoshimatsu567 - youbicode - youngvform - yudai-nkt diff --git a/docs/discussion/server-vs-client.md b/docs/discussion/server-vs-client.md index d1700db8464..22fd6d73b60 100644 --- a/docs/discussion/server-vs-client.md +++ b/docs/discussion/server-vs-client.md @@ -99,13 +99,13 @@ export default function Component() { ## Forcing Code Out of the Browser or Server Builds -You can force code out of either the client or the server with the [`*.client.tsx`][file_convention_client] and [`*.server.tsx`][file_convention_server] conventions. +You can force code out of either the client or the server with the [`*.client.ts`][file_convention_client] and [`*.server.ts`][file_convention_server] conventions. -While rare, sometimes server code makes it to client bundles because of how the compiler determines the dependencies of a route module, or because you accidentally try to use it in code that needs to ship to the client. You can force it out by adding `*.server.tsx` on the end of the file name. +While rare, sometimes server code makes it to client bundles because of how the compiler determines the dependencies of a route module, or because you accidentally try to use it in code that needs to ship to the client. You can force it out by adding `*.server.ts` on the end of the file name. For example, we could name a module `app/user.server.ts` instead of `app/user.ts` to ensure that the code in that module is never bundled into the client — even if you try to use it in the component. -Additionally, you may depend on client libraries that are unsafe to even bundle on the server — maybe it tries to access [`window`][window_global] by simply being imported. You can likewise remove these modules from the server build by appending `*.client.tsx` to the file name. +Additionally, you may depend on client libraries that are unsafe to even bundle on the server — maybe it tries to access [`window`][window_global] by simply being imported. You can likewise remove these modules from the server build by appending `*.client.ts` to the file name. [action]: ../route/action [headers]: ../route/headers diff --git a/docs/file-conventions/routes.md b/docs/file-conventions/routes.md index 5f62e943617..f695323e82d 100644 --- a/docs/file-conventions/routes.md +++ b/docs/file-conventions/routes.md @@ -333,7 +333,7 @@ app/ │ │ └── scroll-experience.tsx │ ├── _landing.about/ │ │ ├── employee-profile-card.tsx -│ │ ├── get-employee-data.server.tsx +│ │ ├── get-employee-data.server.ts │ │ ├── route.tsx │ │ └── team-photo.jpg │ ├── _landing/ @@ -344,7 +344,7 @@ app/ │ │ ├── route.tsx │ │ └── stats.tsx │ ├── app.projects/ -│ │ ├── get-projects.server.tsx +│ │ ├── get-projects.server.ts │ │ ├── project-buttons.tsx │ │ ├── project-card.tsx │ │ └── route.tsx @@ -355,7 +355,7 @@ app/ │ ├── app_.projects.$id.roadmap/ │ │ ├── chart.tsx │ │ ├── route.tsx -│ │ └── update-timeline.server.tsx +│ │ └── update-timeline.server.ts │ └── contact-us.tsx └── root.tsx ``` diff --git a/docs/future/vite.md b/docs/future/vite.md index cf05a57050d..0b28e47b700 100644 --- a/docs/future/vite.md +++ b/docs/future/vite.md @@ -164,10 +164,17 @@ export async function loader({ If you'd like to add additional properties to the load context, you should export a `getLoadContext` function from a shared module so that **load context in Vite, Wrangler, and Cloudflare Pages are all augmented in the same way**: -```ts filename=load-context.ts lines=[1,9,13-26] +```ts filename=load-context.ts lines=[1,4-9,20-33] import { type AppLoadContext } from "@remix-run/cloudflare"; import { type PlatformProxy } from "wrangler"; +// When using `wrangler.toml` to configure bindings, +// `wrangler types` will generate types for those bindings +// into the global `Env` interface. +// Need this empty interface so that typechecking passes +// even if no `wrangler.toml` exists. +interface Env {} + type Cloudflare = Omit, "dispose">; declare module "@remix-run/cloudflare" { @@ -1061,7 +1068,7 @@ We currently recommend excluding the plugin when used with other Vite-based tool For Vitest: -```ts filename=vite.config.ts lines=[7,12-13] +```ts filename=vite.config.ts lines=[5] import { vitePlugin as remix } from "@remix-run/dev"; import { defineConfig, loadEnv } from "vite"; diff --git a/docs/guides/file-uploads.md b/docs/guides/file-uploads.md index df8215b6764..c2c1bcfbeba 100644 --- a/docs/guides/file-uploads.md +++ b/docs/guides/file-uploads.md @@ -101,7 +101,7 @@ Your job is to do whatever you need with the `data` and return a value that's a We have the built-in `unstable_createFileUploadHandler` and `unstable_createMemoryUploadHandler` and we also expect more upload handler utilities to be developed in the future. If you have a form that needs to use different upload handlers, you can compose them together with a custom handler, here's a theoretical example: -```tsx filename=file-upload-handler.server.tsx +```ts filename=file-upload-handler.server.ts import type { UploadHandler } from "@remix-run/node"; // or cloudflare/deno import { unstable_createFileUploadHandler } from "@remix-run/node"; // or cloudflare/deno import { createCloudinaryUploadHandler } from "some-handy-remix-util"; diff --git a/docs/guides/templates.md b/docs/guides/templates.md index 7db4b929286..ef0314c86b8 100644 --- a/docs/guides/templates.md +++ b/docs/guides/templates.md @@ -35,6 +35,9 @@ npx create-remix@latest --template remix-run/remix/templates/cloudflare-workers npx create-remix@latest --template remix-run/remix/templates/deno npx create-remix@latest --template remix-run/remix/templates/express npx create-remix@latest --template remix-run/remix/templates/fly +npx create-remix@latest --template remix-run/remix/templates/vite-cloudflare +npx create-remix@latest --template remix-run/remix/templates/vite-express +npx create-remix@latest --template remix-run/remix/templates/vite ## SPA Mode npx create-remix@latest --template remix-run/remix/templates/spa diff --git a/docs/hooks/use-fetcher.md b/docs/hooks/use-fetcher.md index dce3dd6fa09..3998ac9ae37 100644 --- a/docs/hooks/use-fetcher.md +++ b/docs/hooks/use-fetcher.md @@ -70,21 +70,40 @@ The `formData` can be multiple types: - [`FormData`][form_data] - A `FormData` instance. - [`HTMLFormElement`][html_form_element] - A [`
`][form_element] DOM element. -- `Object` - An object of key/value pairs that will be converted to a `FormData` instance. +- `Object` - An object of key/value pairs that will be converted to a `FormData` instance by default. You can pass a more complex object and serialize it as JSON by specifying `encType: "application/json"`. See [`useSubmit`][use-submit] for more details. If the method is `GET`, then the route [`loader`][loader] is being called and with the `formData` serialized to the url as [`URLSearchParams`][url_search_params]. If `DELETE`, `PATCH`, `POST`, or `PUT`, then the route [`action`][action] is being called with `formData` as the body. ```tsx +// Submit a FormData instance (GET request) +const formData = new FormData(); +fetcher.submit(formData); + +// Submit the HTML form element fetcher.submit(event.currentTarget.form, { method: "POST", }); +// Submit key/value JSON as a FormData instance fetcher.submit( { serialized: "values" }, { method: "POST" } ); -fetcher.submit(formData); +// Submit raw JSON +fetcher.submit( + { + deeply: { + nested: { + json: "values", + }, + }, + }, + { + method: "POST", + encType: "application/json", + } +); ``` `fetcher.submit` is a wrapper around a [`useSubmit`][use-submit] call for the fetcher instance, so it also accepts the same options as `useSubmit`. diff --git a/integration/root-route-test.ts b/integration/root-route-test.ts index 95a6f0d1fc3..b72ee98b1e6 100644 --- a/integration/root-route-test.ts +++ b/integration/root-route-test.ts @@ -148,7 +148,6 @@ test.describe("root route", () => { let app = new PlaywrightFixture(appFixture, page); await app.goto("/"); await page.waitForSelector("h1"); - console.log(await app.getHtml()); expect(await app.getHtml("title")).toMatch("Layout Title"); expect(await app.getHtml("h1")).toMatch("Application Error"); diff --git a/integration/spa-mode-test.ts b/integration/spa-mode-test.ts index 7063399405a..e381287703b 100644 --- a/integration/spa-mode-test.ts +++ b/integration/spa-mode-test.ts @@ -583,6 +583,8 @@ test.describe("SPA Mode", () => { let html = await res.text(); expect(html.match(/ { + for (let key in ReactRouterDOM) { + if (nonReExportedKeys.has(key)) { + it(`does not re-export ${key} from react-router`, () => { + expect(RemixReact[key] === undefined).toBe(true); + }); + } else if (modifiedExports.has(key)) { + it(`re-exports a different version of ${key}`, () => { + expect(RemixReact[key] !== undefined).toBe(true); + expect(RemixReact[key] !== ReactRouterDOM[key]).toBe(true); + }); + } else { + it(`re-exports ${key} from react-router`, () => { + expect(RemixReact[key] === ReactRouterDOM[key]).toBe(true); + }); + } + } +}); diff --git a/packages/remix-react/errorBoundaries.tsx b/packages/remix-react/errorBoundaries.tsx index abb47214e57..5f9caf4d723 100644 --- a/packages/remix-react/errorBoundaries.tsx +++ b/packages/remix-react/errorBoundaries.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import type { Location } from "@remix-run/router"; import { isRouteErrorResponse } from "react-router-dom"; -import { useRemixContext } from "./components"; +import { Scripts, useRemixContext } from "./components"; type RemixErrorBoundaryProps = React.PropsWithChildren<{ location: Location; @@ -66,12 +66,25 @@ export class RemixErrorBoundary extends React.Component< export function RemixRootDefaultErrorBoundary({ error }: { error: unknown }) { console.error(error); + let heyDeveloper = ( +