stack icon indicating copy to clipboard operation
stack copied to clipboard

Issue: Stack-auth and Localization Redirection Conflict

Open diogoparente opened this issue 1 year ago • 6 comments

Hey everyone 👋

I’m using stack-auth successfully in my non-localized app, and the localized version works fine without stack-auth. However, after merging both, I’m encountering an issue: after signing in, I’m redirected back to /handler/sign-in instead of the afterSignInUrl I’ve defined.

Is there any documentation or guidance on handling this scenario? I checked the middleware examples, but they didn’t seem to resolve the issue.

I'm looking to be redirected to the specified afterSignIn but localised.

Thanks!

diogoparente avatar Sep 11 '24 15:09 diogoparente

So, I've fixed my use-case with some workarounds and route hacking, but I'm still looking for a better approach, if possible.

Here's how I did it:


import { i18n } from "./i18n.config";

import { match as matchLocale } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";

import { NextResponse } from "next/server";

function getLocale(request: NextRequest): string | undefined {
  // Negotiator expects plain object so we need to transform headers
  const negotiatorHeaders: Record<string, string> = {};
  request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));

  // @ts-ignore locales are readonly
  const locales: string[] = i18n.locales;

  // Use negotiator and intl-localematcher to get best locale
  let languages = new Negotiator({ headers: negotiatorHeaders }).languages(
    locales
  );

  const locale = matchLocale(languages, locales, i18n.defaultLocale);

  return locale;
}
export async function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;

  // List of routes that should bypass locale redirection
  const nonLocalizedPaths = [
    "/handler/signin",
    "/handler/sign-in",
    "/handler/signup",
    "/handler/sign-up",
    "/handler/oauth-callback",
    "/handler/account-settings",
  ];

  // Check if the pathname matches any non-localized paths
  if (nonLocalizedPaths.includes(pathname)) {
    return NextResponse.next();
  }

  // Iterate over all locales, check and strip the locale prefix
  const localeMatch = i18n.locales.find((locale) =>
    pathname.startsWith(`/${locale}/`)
  );

  if (localeMatch) {
    const strippedPath = pathname.replace(`/${localeMatch}`, "");

    // Handle specific paths after stripping the locale
    if (
      strippedPath === "/handler/sign-in" ||
      strippedPath === "/handler/sign-up" ||
      strippedPath === "/handler/oauth-callback"
    ) {
      request.nextUrl.pathname = strippedPath.replace("/sign-in", "/signin"); // Normalize path
      return NextResponse.next();
    }
  }

  // Ignore specific files (manifest, favicon, PNGs)
  if (
    ["/manifest.json", "/favicon.ico"].includes(pathname) ||
    /\/.*\.png$/.test(pathname)
  ) {
    return;
  }

  // If pathname is missing a locale, redirect
  const pathnameIsMissingLocale = i18n.locales.every(
    (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
  );

  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);
    return NextResponse.redirect(
      new URL(
        `/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
        request.url
      )
    );
  }

  return NextResponse.next();
}

export const config = {
  // Matcher ignoring `/_next/` and `/api/`
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

diogoparente avatar Sep 11 '24 17:09 diogoparente

I don't have any idea on how to solve your issue, but just FYI: you can try https://github.com/amannn/next-intl, it has first class support for next.js and it is being used in big projects like https://nodejs.org. I'm also using it and the afterSignInUrl works flawlessly.

Chenalejandro avatar Sep 14 '24 20:09 Chenalejandro

One solution for this is that we can make all the URLs like afterSignIn an optional function so you can decide dynamically where to redirect them. Does that maybe solve your problem?

fomalhautb avatar Sep 14 '24 20:09 fomalhautb

I don't have any idea on how to solve your issue, but just FYI: you can try https://github.com/amannn/next-intl, it has first class support for next.js and it is being used in big projects like https://nodejs.org. I'm also using it and the afterSignInUrl works flawlessly.

Thanks for the help. I was also using it before, but decided to move on without a library for that purpose. If this ends up persisting, I might go back to next-intl and check if it solves the problem.

diogoparente avatar Sep 15 '24 08:09 diogoparente

One solution for this is that we can make all the URLs like afterSignIn an optional function so you can decide dynamically where to redirect them. Does that maybe solve your problem?

Hey there. If there is no way to predict a localised url yet, I guess it would help indeed.

It would also be cool do have the same support for the sign-in and sign-up urls so we don't have to run this hardcoded routing handling in middleware.ts.

What do you think?

diogoparente avatar Sep 15 '24 08:09 diogoparente

One solution for this is that we can make all the URLs like afterSignIn an optional function so you can decide dynamically where to redirect them. Does that maybe solve your problem?

Hey there. If there is no way to predict a localised url yet, I guess it would help indeed.

It would also be cool do have the same support for the sign-in and sign-up urls so we don't have to run this hardcoded routing handling in middleware.ts.

What do you think?

That is the idea, I think we are going to rework the redirect process to make it more generalized

fomalhautb avatar Sep 24 '24 17:09 fomalhautb

Closing as duplicate of the i18n overhaul meta issue https://github.com/stack-auth/stack-auth/issues/1047 .

The current localization system is being completely replaced, which will resolve the vast majority of translation bugs and enable proper support for new languages.

Once the rewrite is complete, any remaining problems will be re-opened or filed as fresh issues.

→ See https://github.com/stack-auth/stack-auth/issues/1047 for status and progress.

Thank you for the report! 🌍

madster456 avatar Dec 05 '25 22:12 madster456