Thanks for sharing the details and the screenshot! I see you’re experiencing an issue where Web3Auth works on desktop browsers but not on mobile browsers when using the PnP Web SDK with Next.js page routes.
Here’s a summary of your issue for the support team:
Issue Summary
- SDK: Web3Auth Plug and Play (PnP) Web SDK
- Framework: Next.js (using page routes)
- Platform: Works on desktop browsers, fails on mobile browsers
- Error Evidence: Screenshot provided
- Integration Context: Using Web3Auth with Next.js, encountering issues specifically on mobile browsers
Next Steps & Information Needed
To help the support team debug this faster, could you please provide:
-
Web3Auth Initialization & Login Code:
Please share the code snippets where you initialize and invoke the Web3Auth login in your Next.js app. This helps us check if there are any mobile-specific configurations missing. -
SDK Version Number:
Which version of the PnP Web SDK are you using? (e.g.,@web3auth/modal
version) -
Mobile Browser Details:
Which mobile browsers (and versions) have you tested? Is the issue present on both iOS and Android? -
Console Logs or Errors:
If possible, open the browser console on your mobile device (or use remote debugging tools) and share any error messages you see when trying to log in.
Common Troubleshooting Steps
- Mobile Support: Ensure you are using the Web3Auth Modal SDK which is designed for both desktop and mobile browsers.
- Next.js Routing: If you are using custom routes or server-side rendering, make sure the SDK is only initialized on the client side, as it requires a browser environment.
- Redirect URLs: Double-check that your redirect URLs are correctly set up for mobile browsers, as some mobile browsers handle redirects differently.
For more details, check the Web3Auth Next.js Quick Start Guide and the Integration Checklist.
Once you provide the code snippets and the above details, the support team will be able to assist you further! Thank you for your patience.
Note: This response was generated by an AI bot and may require further verification. The Web3Auth support team has tracked this issue and will be responding as soon as possible.
Additionally, we would recommend you to join our biweekly Office Hours to get this resolved even faster. Web3Auth Developer Office Hours
import { createContext, useContext } from “react”;
import {
useWeb3Auth as useWeb3AuthMain,
Web3AuthProvider as Web3AuthModalProvider,
} from “@web3auth/modal/react”;
import {
useWeb3AuthConnect,
useWeb3AuthDisconnect,
useWeb3AuthUser,
useWalletUI,
} from “@web3auth/modal/react”;
const Web3AuthContext = createContext(null);
import {
walletServicesPlugin,
WEB3AUTH_NETWORK,
WALLET_CONNECTORS,
} from “@web3auth/modal”;
const clientId = process.env.NEXT_PUBLIC_CLIENT_ID;
const chainConfig = JSON.parse(process.env.NEXT_PUBLIC_CHAIN_CONFIG);
const chainNamespace = process.env.NEXT_PUBLIC_CHAIN_NAME_SPACE;
chainConfig.chainNamespace = chainNamespace;
const web3AuthNetwork = process.env.NEXT_PUBLIC_WEB3AUTH_NETWORK;
const appUrl = process.env.NEXT_PUBLIC_APP_URL;
const verifier = process.env.NEXT_PUBLIC_WEB3AUTH_VERIFIER;
const redirectUrl =
typeof window !== “undefined”
? ${window.location.origin}/auth
// dynamic deep link
: “http://studiodn.openledger.dev/auth”;
const web3AuthContextConfig = {
web3AuthOptions: {
clientId,
web3AuthNetwork,
//chains: [chainConfig],
defaultChainId: chainConfig?.chainId,
sessionTime: 432000,
redirectUrl: redirectUrl,
walletServicesConfig: {
confirmationStrategy: “modal”,
},
modalConfig: {
connectors: {
[WALLET_CONNECTORS.AUTH]: {
label: “auth”,
loginMethods: {
google: {
name: “google login”,
authConnectionId: verifier,
},
facebook: {
showOnModal: false,
},
email_passwordless: {
showOnModal: false,
},
sms_passwordless: {
showOnModal: false,
},
twitch: {
showOnModal: false,
},
apple: {
showOnModal: false,
},
farcaster: {
showOnModal: false,
},
reddit: {
showOnModal: false,
},
line: {
showOnModal: false,
},
kakao: {
showOnModal: false,
},
wechat: {
showOnModal: false,
},
linkedin: {
showOnModal: false,
},
discord: {
showOnModal: false,
},
twitter: {
showOnModal: false, // hide Twitter login
},
},
showOnModal: true,
},
[WALLET_CONNECTORS.METAMASK]: {
label: “MetaMask”,
showOnModal: true,
},
[WALLET_CONNECTORS.WALLET_CONNECT_V2]: {
label: “MetaMask”,
showOnModal: true,
},
// [WALLET_CONNECTORS.WALLET_CONNECT_V2]: {
// label: “WalletConnect”,
// showOnModal: true,
// },
// [WALLET_CONNECTORS.COINBASE]: {
// label: “Coinbase Wallet”,
// showOnModal: true,
// },
},
hideWalletDiscovery: false,
},
mfaLevel: “none”,
uiConfig: {
appName: “OpenLedger”,
appUrl,
logoLight: “https://cdn.openledger.xyz/Studio/dark-logo-icon.png”,
logoDark: “https://cdn.openledger.xyz/Studio/light-logo-icon.png”,
theme: {
primary: “#3C4FF9”,
},
},
},
};
export default web3AuthContextConfig;
export const Web3AuthProvider = ({ children }) => {
return (
<Web3AuthContext.Provider value={{}}>{children}</Web3AuthContext.Provider>
);
};
export const useWeb3AuthWallet = () => {
const {
showWalletUI,
loading: walletUILoading,
error: walletUIError,
} = useWalletUI();
return {
wsPluginState: {
showWalletUi: showWalletUI,
},
};
};
“use client”;
import { useEffect, useState } from “react”;
import Image from “next/image”;
import { Button } from “@nextui-org/react”;
import GoogleIcon from “…/…/public/assets/images/icons/google.svg”;
import { useDispatch, useSelector } from “react-redux”;
import { setUserDetails, setWeb3UserInfo, userLogout } from “@/redux/reducers/auth”;
import { getCookies, removeCookies, setCookies } from “@/utils/cookie”;
import { getSIWEMessage } from “@/utils/siwe”;
import {
AuthApi,
loginApi,
nonceApi,
SIWEApi,
getProfileApi,
} from “@/apis/auth”;
import { ethers } from “ethers”;
import { useRouter } from “next/navigation”;
import { showToast } from “@/utils/toast”;
import { useWeb3Auth, useWeb3AuthUser } from “@/context/web3AuthContextConfig”;
// Main Component
export default function LoginComponent() {
const [isLoading, setIsLoading] = useState(false);
const dispatch = useDispatch();
const router = useRouter();
const authToken = getCookies(“authToken”);
const { provider, web3Auth } = useWeb3Auth();
const { userInfo } = useWeb3AuthUser();
const { web3UserInfo } = useSelector((state) => state.auth);
// -------------------
// Get Nonce
// -------------------
const getNonce = async () => {
try {
const response = await nonceApi();
return response.data.data?.nonce || “”;
} catch (e) {
console.error(“Nonce fetch failed”, e);
return “”;
}
};
// -------------------
// Google Login Handler
// -------------------
const googleHandleLogin = async () => {
setIsLoading(true);
try {
if (!provider) throw new Error(“No provider found”);
const ethersProvider = new ethers.BrowserProvider(provider);
const signer = await ethersProvider.getSigner();
const address = await signer.getAddress();
// Step 1: Get Nonce
const nonce = await getNonce();
if (!nonce) throw new Error("Nonce not received");
// Step 2: Generate SIWE Message
const message = getSIWEMessage(address, nonce);
const signature = await signer.signMessage(message);
// Step 3: Verify SIWE
const siweResponse = await SIWEApi({ message, signature });
if (!siweResponse?.data?.success) throw new Error("SIWE verification failed");
// Step 4: Login to Backend
const { data: loginData } = await loginApi({
userId: userInfo?.verifierId,
email: userInfo?.email,
name: userInfo?.name,
profileImage: userInfo?.profileImage,
});
const { authToken, user } = loginData.data;
// Save Token & User Info
setCookies("authToken", authToken, { expires: 7, path: "/" });
dispatch(setUserDetails(user));
dispatch(setWeb3UserInfo(userInfo));
showToast("Login successful!", "success");
router.push("/"); // Redirect after login
} catch (error) {
console.error("Google Login Error:", error);
showToast("Login failed. Please try again.", "error");
} finally {
setIsLoading(false);
}
};
// -------------------
// Logout Handler
// -------------------
const handleLogout = async () => {
setIsLoading(true);
try {
if (web3Auth && typeof web3Auth.logout === “function”) {
await web3Auth.logout();
}
} catch (error) {
console.error(“Logout error:”, error);
} finally {
dispatch(userLogout());
removeCookies();
setIsLoading(false);
router.push(“/”);
}
};
// -------------------
// Auto Login if Connected
// -------------------
useEffect(() => {
const autoLogin = async () => {
if (!authToken && userInfo && web3UserInfo) {
try {
const { data: loginData } = await loginApi({
userId: userInfo?.verifierId,
email: userInfo?.email,
name: userInfo?.name,
profileImage: userInfo?.profileImage,
});
const { authToken, user } = loginData.data;
setCookies("authToken", authToken, { expires: 7, path: "/" });
dispatch(setUserDetails(user));
dispatch(setWeb3UserInfo(userInfo));
} catch (error) {
console.error("Auto login error:", error);
}
}
};
autoLogin();
}, [authToken, userInfo, web3UserInfo, dispatch]);
// -------------------
// UI Render
// -------------------
return (
<Button
type=“button”
color=“primary”
className=“w-full h-12 bg-[#3C4FF9] border border-[#3C4FF9] min-w-[3rem] sm:min-w-[5rem] transition-colors duration-200 font-semibold mb-4”
onPress={!authToken ? googleHandleLogin : undefined}
isLoading={isLoading}
isDisabled={isLoading}
endContent={
}
>
{isLoading
? “Connecting…”
: !authToken
? “Login With Google”
: “Logged In”}
{authToken && (
<Button
type="button"
color="danger"
className="w-full h-12 border min-w-[3rem] sm:min-w-[5rem] transition-colors duration-200 font-semibold"
onPress={handleLogout}
isLoading={isLoading}
>
Logout
</Button>
)}
</div>
);
}
Web3Auth works in desktop browsers but does not work in mobile browsers when implemented with Next.js page routes ? its working page routes ?
please provide sample code page route