pwa-kit icon indicating copy to clipboard operation
pwa-kit copied to clipboard

[FEATURE] Support 301 redirects

Open xusoo opened this issue 4 months ago • 0 comments

Hi!

I noticed that there is no way to force a 301 redirect from React code (not from ssr.js). I tried the following:

  • Use res.redirect(301, url) (using useServerContext()) but this throws an error "Cannot set headers after they are sent to the client"
  • Use <Redirect> component but this one always uses a 302 because the return status is hard-coded in @salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js

So the first question would be if there is any way to solve the first error.

But, in any case, my proposal here is to allow passing a custom status when redirecting, following the example of the React Router documentation, you could add a new component to PWA Kit:

const RedirectWithStatus = function RedirectWithStatus({status, ...props}) {
    return (
        <Route
            render={({staticContext}) => {
                if (staticContext) staticContext.status = status
                return <Redirect {...props} />
            }}
        />
    )
}

// Use it like this
return <RedirectWithStatus status={301} to={...} />

But as I said, in order to support that on the server there's a change needed in @salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js file:

diff --git a/node_modules/@salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js b/node_modules/@salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js
index d6ec3c8..d2697e2 100644
--- a/node_modules/@salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js
+++ b/node_modules/@salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js
@@ -240,7 +240,7 @@ const render = exports.render = /*#__PURE__*/function () {
       res.setHeader('Server-Timing', res.__performanceTimer.buildServerTimingHeader());
     }
     if (redirectUrl) {
-      res.redirect(302, redirectUrl);
+      res.redirect(routerContext?.status || 302, redirectUrl);
     } else {
       res.status(status).send(html);
     }

The motivation for this is purely SEO. If you want to redirect to the canonical URL, or migrate old URLs to a new structure, etc. the crawlers need to understand this is a permanent redirect (301) to not index both pages.

Looking forward for any feedback and hopefully for this to get implemented into pwa-kit :)

Thanks!

xusoo avatar Oct 22 '24 17:10 xusoo