-
Notifications
You must be signed in to change notification settings - Fork 9
fix: Add is404
flag for 404ed routes
#151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
fix: Add is404
flag for 404ed routes
#151
Conversation
chore: Add `import/no-default-export` eslint rule.
🦋 Changeset detectedLatest commit: 680b91d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@justlevine This here is a quick fix as recommended by @ayushnirwal: |
Pull Request Test Coverage Report for Build 14464649106Details
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with some small notes below.
That said, since this PR doesn't seem to actually do anything with / allow usage of is404
and since connectedNode
is an unnecessary perf hit. I'm going to put this on hold.
If exposing template date or fixing the error codes gets unblocked before snapwp-helper
can expose a templateByUri.is404
, then we'll merge this as a temporary fix. Otherwise, we'll update this to use that eventual field.
@@ -51,13 +52,15 @@ export function parseQueryResult( | |||
} | |||
|
|||
const templateByUri = queryData.data?.templateByUri; | |||
const is404 = templateByUri?.connectedNode === null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const is404 = templateByUri?.connectedNode === null; | |
// @todo templateByUri should expose a `is404` field to avoid the perf hit from connectedNode. | |
const is404 = templateByUri?.connectedNode === null; |
@@ -29,6 +29,7 @@ export function parseQueryResult( | |||
scripts: EnqueuedScriptProps[] | undefined; | |||
scriptModules: ScriptModuleProps[] | undefined; | |||
bodyClasses: string[] | undefined; | |||
is404: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ayushnirwal taking into consideration future-compat with other protentional route-based conditionals: is this the ideal schema shape for consumption?
@ayushnirwal This PR for now just returns the |
In const { editorBlocks, bodyClasses, stylesheets, scripts, scriptModules, is404 } =
await getTemplateData( pathname || '/' );
<main>
<div className="wp-site-blocks">
{ children( { editorBlocks, is404 } ) }
</div>
</main> export default function Page() {
return (
<TemplateRenderer>
{ ( { editorBlocks, is404 } ) => {
return <EditorBlocksRenderer editorBlocks={ editorBlocks } />;
} }
</TemplateRenderer>
);
} We can expose the is404 to user land this way. |
We can redirect to next's 404 page if is404 is true. If next provides ways to attach status code we can do that. |
The acceptance criteria for https://github.com/rtCamp/headless/issues/451 is to use WordPress as the source of truth for the 404 template while providing user control of status codes based on WPGraphQL-exposed data. I don't think a component-level redirect is an "ideal" DX solve for this, but we can refine it in a follow-up PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.
Files not reviewed (1)
- packages/query/src/queries/get-current-template.graphql: Language not supported
Comments suppressed due to low confidence (1)
packages/query/src/utils/tests/parse-template.test.ts:90
- There is no test case for when 'templateByUri' is undefined; consider adding one to ensure the 'is404' flag defaults to false in that scenario.
});
Not a big fan of doing this, because the user won't be able to control what is to be done if the page is a 404 page. |
@ayushnirwal @justlevine I have updated the current path middleware to perform the is404 check. |
response.headers.set( 'x-current-path', pathname ); | ||
response.headers.set( 'x-snapwp-is404', String( is404 ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a custom header? Why would we want a custom header?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was added for testing purposes. Removing it now.
children: ( editorBlocks: BlockData[] ) => ReactNode; | ||
children: ( args: { | ||
editorBlocks: BlockData[]; | ||
is404: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can get this out of getTemplateData()
we do we also need to expose it directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not entirely sure what you mean here. I assume you mean one of these:
Why is 404 status added to the response when we can get is404 out of getTemplateData()
?
- Acceptance criteria. We can get rid of this flag in template renderer if @ayushnirwal says so.
Why do we need a separate function to get 404 status?
getTemplateData
processes a bigGetCurrentTemplate
query, which has other fields. All we need for now is theconnectedNode
, so it makes sense to have it separate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it was your first guess: I was asking about the line I commented on: the is404
param that we're passing to the children.
Can you point me to where that acceptance criteria is listed? Afaik I'm the one who specced both #150 and https://gihtub.com/rtCamp/headless/issues/451 not @ayushnirwal (though obviously if Ayush - or you - has a compelling case for why we need it, I'm happy to defer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From #145 (comment):
This is meant to be a quick fix to add a status code to the response. The changes to the parser may be moved to Template rendering. After #123
From #151 (comment):
If next provides ways to attach status code we can do that.
This wasn't acceptance criteria, but what Ayush suggested. I think it makes sense to have the status code as 404, instead of letting it be 200, and passing is404: true
to the user.
The bigger caveat is that you shouldn't be querying data in middleware altogether... If you can avoid it. Not entirely sure the purpose of all this logic, but my assumption is that the status handling needs to happen in a route handler, not middleware. @ayushnirwal ? |
We cannot render JSX ( |
@Swanand01 I don't know how you arrived at the middleware solution. Try using the notFound function along with not-found.js file.
@justlevine Is there a reliable URI to get the 404 template in (1) through templateByURI? or any other way? If no, we can use a garbage URI to fetch 404 template data for now and later update the backend to remove the hack. |
What if we use export default function NotFound() {
return (
<TemplateRenderer>
{ ( { editorBlocks } ) => {
return <EditorBlocksRenderer editorBlocks={ editorBlocks } />;
} }
</TemplateRenderer>
);
} |
Yes... |
There's currently no way to fetch just a template and not a "resolved" URI. Ideally it would be the same results of the previous query - either via the app or because we have server-side caching. I know most things are locked down, but even just requerying the same URI will give us what we need.
I'm not opposed to this as a temporary workaround. |
What
This PR adds the
is404
flag for 404ed routesWhy
Currently, when templateByUri{} resolves to a non-existent WordPress route, the 404 template gets returned, but since theres a template to return, the status code presents as a Success, instead of properly indicating (to SEO, crawlers, userland handlers) that there is no WP-route at that page.
Related Issue(s):
How
parseQueryResult
inpackages/query/src/utils/parse-template.ts
is refactored to also parse out the flagis404
.Testing Instructions
Screenshots
Additional Info
Checklist
npm run changeset
.