Skip to content

Commit

Permalink
Handle isbot v4 in a backwards-compatible manner (#8415)
Browse files Browse the repository at this point in the history
Co-authored-by: Filip Bel <bel.filip@icloud.com>
  • Loading branch information
brophdawg11 and fifi98 authored Jan 3, 2024
1 parent cc8d695 commit 131bcca
Show file tree
Hide file tree
Showing 39 changed files with 129 additions and 56 deletions.
9 changes: 9 additions & 0 deletions .changeset/isbot-version-four.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@remix-run/dev": patch
---

Fix issue with `isbot` v4 released on 1/1/2024

* `remix dev` wil now add `"isbot": "^4"` to `package.json` instead of using `latest`
* Update built-in `entry.server` files to work with both `isbot@3` and `isbot@4` for backwards-compatibility with Remix apps that have pinned `isbot` to v3
* Templates are updated to use `isbot@4` moving forward via `create-remix`
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
- fergusmeiklejohn
- fernandojbf
- fgiuliani
- fifi98
- fishel-feng
- francisudeji
- frandiox
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/migrating-react-router-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import type {
} from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";

const ABORT_DELAY = 5_000;
Expand All @@ -66,7 +66,7 @@ export default function handleRequest(
remixContext: EntryContext,
loadContext: AppLoadContext
) {
return isbot(request.headers.get("user-agent"))
return isbot(request.headers.get("user-agent") || "")
? handleBotRequest(
request,
responseStatusCode,
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The Remix compiler will not do any type checking (it simply removes the types).
"@remix-run/node": "latest",
"@remix-run/react": "latest",
"@remix-run/serve": "latest",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
2 changes: 1 addition & 1 deletion docs/start/v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ Remix v2 also no longer exports these polyfilled implementations from `@remix-ru
- import { Response } from "@remix-run/node"; // or cloudflare/deno
+ import { createReadableStreamFromReadable } from "@remix-run/node"; // or cloudflare/deno
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";

const ABORT_DELAY = 5_000;
Expand Down
4 changes: 2 additions & 2 deletions integration/defer-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,7 @@ test.describe("aborted", () => {
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";
const ABORT_DELAY = 1;
Expand All @@ -997,7 +997,7 @@ test.describe("aborted", () => {
remixContext: EntryContext,
loadContext: AppLoadContext
) {
return isbot(request.headers.get("user-agent"))
return isbot(request.headers.get("user-agent") || "")
? handleBotRequest(
request,
responseStatusCode,
Expand Down
2 changes: 1 addition & 1 deletion integration/helpers/vite-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@remix-run/node": "*",
"@remix-run/react": "*",
"@remix-run/serve": "*",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
2 changes: 1 addition & 1 deletion integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"get-port": "^5.1.1",
"glob": "8.0.3",
"globby": "^11.1.0",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"npm-run-all": "^4.1.5",
"pidtree": "^0.6.0",
"postcss": "^8.4.19",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@remix-run/cloudflare-pages": "*",
"@remix-run/css-bundle": "*",
"@remix-run/react": "*",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@remix-run/dev/server-build": "https://esm.sh/@remix-run/dev@1.16.0/server-build",
"@remix-run/react": "https://esm.sh/@remix-run/react@1.16.0",
"@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@1.16.0",
"isbot": "https://esm.sh/isbot@^3.6.8",
"isbot": "https://esm.sh/isbot@^4.1.0",
"react": "https://esm.sh/react@^18.2.0",
"react-dom": "https://esm.sh/react-dom@^18.2.0",
"react-dom/client": "https://esm.sh/react-dom@^18.2.0/client",
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-dev/__tests__/fixtures/deno/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@remix-run/css-bundle": "*",
"@remix-run/deno": "*",
"@remix-run/react": "*",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-dev/__tests__/fixtures/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@remix-run/node": "*",
"@remix-run/react": "*",
"@remix-run/serve": "*",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-dev/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ export async function resolveConfig(
pkgJson.update({
dependencies: {
...pkgJson.content.dependencies,
isbot: "latest",
isbot: "^4",
},
});

Expand Down
25 changes: 23 additions & 2 deletions packages/remix-dev/config/defaults/entry.server.cloudflare.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AppLoadContext, EntryContext } from "@remix-run/cloudflare";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import * as isbotModule from "isbot";
import { renderToReadableStream } from "react-dom/server";

export default async function handleRequest(
Expand All @@ -22,7 +22,7 @@ export default async function handleRequest(
}
);

if (isbot(request.headers.get("user-agent"))) {
if (isBotRequest(request.headers.get("user-agent"))) {
await body.allReady;
}

Expand All @@ -32,3 +32,24 @@ export default async function handleRequest(
status: responseStatusCode,
});
}

// We have some Remix apps in the wild already running with isbot@3 so we need
// to maintain backwards compatibility even though we want new apps to use
// isbot@4. That way, we can ship this as a minor Semver update to @remix-run/dev.
function isBotRequest(userAgent: string | null) {
if (!userAgent) {
return false;
}

// isbot >= 3.8.0, >4
if ("isbot" in isbotModule && typeof isbotModule.isbot === "function") {
return isbotModule.isbot(userAgent);
}

// isbot < 3.8.0
if ("default" in isbotModule && typeof isbotModule.default === "function") {
return isbotModule.default(userAgent);
}

return false;
}
25 changes: 23 additions & 2 deletions packages/remix-dev/config/defaults/entry.server.deno.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AppLoadContext, EntryContext } from "@remix-run/deno";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import * as isbotModule from "isbot";
import { renderToReadableStream } from "react-dom/server";

export default async function handleRequest(
Expand All @@ -22,7 +22,7 @@ export default async function handleRequest(
}
);

if (isbot(request.headers.get("user-agent"))) {
if (isBotRequest(request.headers.get("user-agent"))) {
await body.allReady;
}

Expand All @@ -32,3 +32,24 @@ export default async function handleRequest(
status: responseStatusCode,
});
}

// We have some Remix apps in the wild already running with isbot@3 so we need
// to maintain backwards compatibility even though we want new apps to use
// isbot@4. That way, we can ship this as a minor Semver update to @remix-run/dev.
function isBotRequest(userAgent: string | null) {
if (!userAgent) {
return false;
}

// isbot >= 3.8.0, >4
if ("isbot" in isbotModule && typeof isbotModule.isbot === "function") {
return isbotModule.isbot(userAgent);
}

// isbot < 3.8.0
if ("default" in isbotModule && typeof isbotModule.default === "function") {
return isbotModule.default(userAgent);
}

return false;
}
25 changes: 23 additions & 2 deletions packages/remix-dev/config/defaults/entry.server.node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PassThrough } from "node:stream";
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import * as isbotModule from "isbot";
import { renderToPipeableStream } from "react-dom/server";

const ABORT_DELAY = 5_000;
Expand All @@ -15,7 +15,7 @@ export default function handleRequest(
remixContext: EntryContext,
loadContext: AppLoadContext
) {
return isbot(request.headers.get("user-agent"))
return isBotRequest(request.headers.get("user-agent"))
? handleBotRequest(
request,
responseStatusCode,
Expand All @@ -30,6 +30,27 @@ export default function handleRequest(
);
}

// We have some Remix apps in the wild already running with isbot@3 so we need
// to maintain backwards compatibility even though we want new apps to use
// isbot@4. That way, we can ship this as a minor Semver update to @remix-run/dev.
function isBotRequest(userAgent: string | null) {
if (!userAgent) {
return false;
}

// isbot >= 3.8.0, >4
if ("isbot" in isbotModule && typeof isbotModule.isbot === "function") {
return isbotModule.isbot(userAgent);
}

// isbot < 3.8.0
if ("default" in isbotModule && typeof isbotModule.default === "function") {
return isbotModule.default(userAgent);
}

return false;
}

function handleBotRequest(
request: Request,
responseStatusCode: number,
Expand Down
4 changes: 2 additions & 2 deletions scripts/playground/template/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PassThrough } from "node:stream";
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";

const ABORT_DELAY = 5000;
Expand All @@ -14,7 +14,7 @@ export default function handleRequest(
remixContext: EntryContext,
loadContext: AppLoadContext
) {
let callbackName = isbot(request.headers.get("user-agent"))
let callbackName = isbot(request.headers.get("user-agent") || "")
? "onAllReady"
: "onShellReady";

Expand Down
2 changes: 1 addition & 1 deletion scripts/playground/template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"bcryptjs": "^2.4.3",
"express": "^4.18.1",
"get-port": "^6.1.2",
"isbot": "^3.5.1",
"isbot": "^4.1.0",
"morgan": "^1.10.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
4 changes: 2 additions & 2 deletions templates/arc/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { PassThrough } from "node:stream";
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";

const ABORT_DELAY = 5_000;
Expand All @@ -24,7 +24,7 @@ export default function handleRequest(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
loadContext: AppLoadContext
) {
return isbot(request.headers.get("user-agent"))
return isbot(request.headers.get("user-agent") || "")
? handleBotRequest(
request,
responseStatusCode,
Expand Down
2 changes: 1 addition & 1 deletion templates/arc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@remix-run/node": "*",
"@remix-run/react": "*",
"cross-env": "^7.0.3",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"source-map-support": "^0.5.21"
Expand Down
4 changes: 2 additions & 2 deletions templates/cloudflare-pages/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import type { AppLoadContext, EntryContext } from "@remix-run/cloudflare";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToReadableStream } from "react-dom/server";

export default async function handleRequest(
Expand All @@ -31,7 +31,7 @@ export default async function handleRequest(
}
);

if (isbot(request.headers.get("user-agent"))) {
if (isbot(request.headers.get("user-agent") || "")) {
await body.allReady;
}

Expand Down
2 changes: 1 addition & 1 deletion templates/cloudflare-pages/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@remix-run/cloudflare-pages": "*",
"@remix-run/css-bundle": "*",
"@remix-run/react": "*",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
4 changes: 2 additions & 2 deletions templates/cloudflare-workers/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import type { AppLoadContext, EntryContext } from "@remix-run/cloudflare";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { isbot } from "isbot";
import { renderToReadableStream } from "react-dom/server";

export default async function handleRequest(
Expand All @@ -31,7 +31,7 @@ export default async function handleRequest(
}
);

if (isbot(request.headers.get("user-agent"))) {
if (isbot(request.headers.get("user-agent") || "")) {
await body.allReady;
}

Expand Down
2 changes: 1 addition & 1 deletion templates/cloudflare-workers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@remix-run/cloudflare": "*",
"@remix-run/css-bundle": "*",
"@remix-run/react": "*",
"isbot": "^3.6.8",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
2 changes: 1 addition & 1 deletion templates/deno/.vscode/resolve_npm_imports.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@remix-run/dev/server-build": "https://esm.sh/@remix-run/dev@1.16.0/server-build",
"@remix-run/react": "https://esm.sh/@remix-run/react@1.16.0",
"@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@1.16.0",
"isbot": "https://esm.sh/isbot@^3.6.8",
"isbot": "https://esm.sh/isbot@^4.1.0",
"react": "https://esm.sh/react@^18.2.0",
"react-dom": "https://esm.sh/react-dom@^18.2.0",
"react-dom/client": "https://esm.sh/react-dom@^18.2.0/client",
Expand Down
Loading

0 comments on commit 131bcca

Please sign in to comment.