'No route matches URL' console errors
lewsmith opened this issue · 4 comments
I've got my sitemaps setup and generating output okay - works like a charm.
However in the console I'm seeing errors about route matching. Example for a /sitemap.txt request, which displays the sitemap fine, but shows this error for every request.
GET /sitemap.xml 200 773 - 1.659 ms
Error: No route matches URL "/robots.txt"
at getInternalRouterError (./node_modules/.pnpm/@remix-run+router@1.9.0/node_modules/@remix-run/router/router.ts:4144:5)
at Object.query (./node_modules/.pnpm/@remix-run+router@1.9.0/node_modules/@remix-run/router/router.ts:2628:19)
at handleDocumentRequestRR (./node_modules/.pnpm/@remix-run+server-runtime@2.0.0_typescript@5.2.2/node_modules/@remix-run/server-runtime/dist/server.js:138:35)
at requestHandler (./node_modules/.pnpm/@remix-run+server-runtime@2.0.0_typescript@5.2.2/node_modules/@remix-run/server-runtime/dist/server.js:63:24)
at ./node_modules/.pnpm/@remix-run+express@2.0.0_express@4.18.2_typescript@5.2.2/node_modules/@remix-run/express/dist/server.js:41:28
I think I've set it up exactly as required in my entry.server.tsx:
import { PassThrough } from 'node:stream';
import {
EntryContext,
createReadableStreamFromReadable,
} from '@remix-run/node';
import { RemixServer } from '@remix-run/react';
import isbot from 'isbot';
import { renderToPipeableStream } from 'react-dom/server';
import { createSitemapGenerator } from 'remix-sitemap';
import { configMeta } from './configs';
const ABORT_DELAY = 5_000;
const { isSitemapUrl, sitemap } = createSitemapGenerator({
siteUrl: configMeta?.url,
generateRobotsTxt: true,
});
export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) {
if (isSitemapUrl(request)) {
return await sitemap(request, remixContext);
}
return isbot(request.headers.get('user-agent'))
? handleBotRequest(
request,
responseStatusCode,
responseHeaders,
remixContext,
)
: handleBrowserRequest(
request,
responseStatusCode,
responseHeaders,
remixContext,
);
}
function handleBotRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) {
return new Promise((resolve, reject) => {
let shellRendered = false;
const { pipe, abort } = renderToPipeableStream(
<RemixServer
context={remixContext}
url={request.url}
abortDelay={ABORT_DELAY}
/>,
{
onAllReady() {
shellRendered = true;
const body = new PassThrough();
responseHeaders.set('Content-Type', 'text/html');
resolve(
new Response(createReadableStreamFromReadable(body), {
headers: responseHeaders,
status: responseStatusCode,
}),
);
pipe(body);
},
onShellError(error: unknown) {
reject(error);
},
onError(error: unknown) {
responseStatusCode = 500;
if (shellRendered) {
console.error(error);
}
},
},
);
setTimeout(abort, ABORT_DELAY);
});
}
function handleBrowserRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) {
return new Promise((resolve, reject) => {
let shellRendered = false;
const { pipe, abort } = renderToPipeableStream(
<RemixServer
context={remixContext}
url={request.url}
abortDelay={ABORT_DELAY}
/>,
{
onShellReady() {
shellRendered = true;
const body = new PassThrough();
responseHeaders.set('Content-Type', 'text/html');
resolve(
new Response(createReadableStreamFromReadable(body), {
headers: responseHeaders,
status: responseStatusCode,
}),
);
pipe(body);
},
onShellError(error: unknown) {
reject(error);
},
onError(error: unknown) {
responseStatusCode = 500;
if (shellRendered) {
console.error(error);
}
},
},
);
setTimeout(abort, ABORT_DELAY);
});
}
One way I managed to stop the error is by creating the route routes/sitemap[.]xml.tsx
and just return null, but that seems a bit hacky.
Have I done something wrong? Does anyone else see this?
Expected behavior
To show either the sitemap or robots file, without the console displaying the errors.
Environment (please complete the following information):
- OS: Manjaro
- Node version: 18
- Remix version: 2.0.0
- remix-sitemap version: 2.2.7
Another way to avoid these errors is to define some routes in the remix config, but I'm not sure if this is any better than creating the two null routes TBH.
E.g.
// remix.confg.js
export default {
...
routes: async (defineRoutes) => {
return defineRoutes((route) => {
route("/sitemap.xml", "routes/_null.tsx", {id: 'routes/sitemap.xml'}),
route("/robots.txt", "routes/_null.tsx", {id: 'routes/robots.txt'})
})
}
};
// routes/_null.tsx
export default function NullRoute() {
return null;
}
I'm seeing the same thing - the sitemap renders fine but I get this:
Error: No route matches URL "/sitemap.xml"
at getInternalRouterError (/Users/justinhandley/IdeaProjects/muzebook/node_modules/.pnpm/@remix-run+router@1.9.0/node_modules/@remix-run/router/router.ts:4144:5)
at Object.query (/Users/justinhandley/IdeaProjects/muzebook/node_modules/.pnpm/@remix-run+router@1.9.0/node_modules/@remix-run/router/router.ts:2628:19)
at handleDocumentRequestRR (/Users/justinhandley/IdeaProjects/muzebook/node_modules/.pnpm/@remix-run+server-runtime@2.0.1_typescript@5.1.6/node_modules/@remix-run/server-runtime/dist/server.js:138:35)
at requestHandler (/Users/justinhandley/IdeaProjects/muzebook/node_modules/.pnpm/@remix-run+server-runtime@2.0.1_typescript@5.1.6/node_modules/@remix-run/server-runtime/dist/server.js:63:24)
at /Users/justinhandley/IdeaProjects/muzebook/node_modules/.pnpm/@remix-run+express@2.0.1_express@4.18.2_typescript@5.1.6/node_modules/@remix-run/express/dist/server.js:41:28
GET /sitemap.xml 200 767 - 53.260 ms
It seems this is a remix v2 bug.
If this doesn't improve in future versions of the remix, it may be necessary to think about somewhere else to put the sitemap response.
Hi @lewsmith @justinhandley to fix this i released a new version (3.1.0) with a new api to just generate the sitemap and robots in each route, i marked it as experimental because i didn't test it on all plataforms.
Here you can see a usage guide https://github.com/fedeya/remix-sitemap/releases/tag/v3.1.0