Redirects to canonical url don't work
sergenux opened this issue · comments
Describe the bug
I try to enable redirects by "redirectToCanonicalSiteUrl: true" but it is don't work.
I found source file in module "src/runtime/nitro/middleware/redirect.ts"
import { defineEventHandler, sendRedirect } from 'h3'
import { joinURL } from 'ufo'
import { useNitroOrigin, useSiteConfig } from '#imports'
export default defineEventHandler((e) => {
const siteConfig = useSiteConfig(e)
if (siteConfig.site) {
const siteConfigHostName = new URL(e.path, siteConfig.site).hostname
const origin = useNitroOrigin(e)
const originHostname = new URL(e.path, origin).hostname
// if origin doesn't match site, do a redirect
if (originHostname !== siteConfigHostName)
return sendRedirect(e, joinURL(siteConfig.site, e.path), 301)
}
})
console.log(siteConfig) outputs the following structure:
{
env: 'production',
name: 'app',
trailingSlash: true,
url: 'https://example.com'
}
siteConfig.site)
is this true or should siteConfig.url
be there?
And other use case if user landed for page "https://example.com/some/path" without trailing slash but in config "trailingSlash: true". Should this redirect to the path with trailing slash?
Thanks for any help.
Reproduction
No response
System / Nuxt Info
No response
I made a temporary solution universal for SPA and SSR mode using router middleware. Maybe it can be useful in some way:
import { withTrailingSlash, withoutTrailingSlash, resolveURL } from "ufo";
import { getRequestURL } from "h3";
import { useRequestEvent, useRequestURL, useError, useSiteConfig } from "#imports";
export default defineNuxtRouteMiddleware(() => {
if (import.meta.prerender) return;
const siteConfig = useSiteConfig();
const error = useError();
const event = useRequestEvent();
const url = event ? getRequestURL(event) : useRequestURL();
const originalUrl = url.href;
let canonicalUrl =
siteConfig.url && !import.meta.dev
? resolveURL(siteConfig.url, url.pathname, url.search, url.hash)
: originalUrl;
if (siteConfig.trailingSlash !== undefined) {
canonicalUrl = siteConfig.trailingSlash
? withTrailingSlash(canonicalUrl, true)
: withoutTrailingSlash(canonicalUrl, true);
}
if (canonicalUrl != originalUrl && !error) {
return navigateTo(canonicalUrl, { redirectCode: 301, external: true });
}
});
When the problem is solved nuxt/nuxt#25763 It might be a little easier:
import { withTrailingSlash, withoutTrailingSlash, resolveURL } from "ufo";
import { useRequestURL, useError, useSiteConfig } from "#imports";
export default defineNuxtRouteMiddleware(() => {
if (import.meta.prerender) return;
const siteConfig = useSiteConfig();
const error = useError();
const url = useRequestURL();
const originalUrl = url.href;
let canonicalUrl =
siteConfig.url && !import.meta.dev
? resolveURL(siteConfig.url, url.pathname, url.search, url.hash)
: originalUrl;
if (siteConfig.trailingSlash !== undefined) {
canonicalUrl = siteConfig.trailingSlash
? withTrailingSlash(canonicalUrl, true)
: withoutTrailingSlash(canonicalUrl, true);
}
if (canonicalUrl != originalUrl && !error) {
return navigateTo(canonicalUrl, { redirectCode: 301, external: true });
}
});