Not working on nextjs
The lib is throwing the following error when next build is ran
ReferenceError: navigator is not defined
at Object.getBrowser (C:\projects\web-ssd-cms-api-bakcend\web-ssd-website-frontend\node_modules\clientjs\src\vendor\deployJava.js:1150:21)
at Object.writePluginTag (C:\projects\web-ssd-cms-api-bakcend\web-ssd-website-frontend\node_modules\clientjs\src\vendor\deployJava.js:1365:24)
at Object.
Even if one puts try catch on the block it still does this, because the issue is in import method. It tries to do something with navigator import time, but I believe it should do anything only when new ClientJS is called
Faced the same issue, any help would be appreciated.
Here is the thing, as I understand it, the lib is doing something on require and not on initialization by constructor.
Here is a working workaround
try {
// This is not working anyway else, it performs an action on require which is
// throwing error build time
const client = require('clientjs')
const browser = new client.ClientJS()
// The rest of the usage
}
catch () {
// Do nothing
}
Didn't work for me, Falling back to fingerprintJs. Thanks for the quick response.
You can create a component that you can import and use dynamically
The component:
import { ClientJS } from 'clientjs'
import { useEffect } from 'react';
export default function ClientJsComponent({ setFingerPrint }) {
useEffect(() => {
const client = new ClientJS();
const fingerprint = client.getFingerprint();
setFingerPrint(fingerprint);
}, [])
return null
}
How to use it
import { useState } from 'react';
import dynamic from 'next/dynamic'
const ClientJs = dynamic(() => import('./components/ClientJs'), { ssr: false });
export default function Page () {
const [fingerPrint, setFingerPrint] = useState()
return (
<>
{fingerPrint}
<ClientJs setFingerPrint={setFingerPrint} />
</>
)
}
Maybe it's not elegant, but it might do it.
Another option is to copy the ClientJs min script to public, load it with <Script src="/ClientJS.min.js" onLoad={doSomething} /> and run a functión when it's ready
You can use the dist/client.base.min.js as described in the docs. This should work without executing any code upon a require call/import. It also has the benefit of being much smaller without losing any functionality on modern browsers.
You can use the
dist/client.base.min.jsas described in the docs. This should work without executing any code upon a require call/import. It also has the benefit of being much smaller without losing any functionality on modern browsers.
thanks!! I have tried and succeeded.
Here is the thing, as I understand it, the lib is doing something on
requireand not oninitializationby constructor. Here is a working workaroundtry { // This is not working anyway else, it performs an action on require which is // throwing error build time const client = require('clientjs') const browser = new client.ClientJS() // The rest of the usage } catch () { // Do nothing }
thanks this code works for me. It solves my "ReferenceError: navigator is not defined" error when I try to build the next.js application. this is how I implemented it... maybe it can help someone...
` const onFinish = async (values: ILogin) => { try { const ClientJs = require("clientjs"); const client = new ClientJs.ClientJS();
const fingerprint = client?.getBrowserData();
const deviceId = client?.getFingerprint();
const data = {
...values,
devicesInfo: {
devicesId: deviceId?.toString(),
devicesModel: fingerprint?.device?.model,
devicesType: fingerprint?.device?.type,
devicesVendor: fingerprint?.device?.vendor,
browserName: fingerprint?.browser?.name,
browserVersion: fingerprint?.browser?.version,
engineName: fingerprint?.engine?.name,
engineVersion: fingerprint?.engine?.version,
osName: fingerprint?.os?.name,
osVersion: fingerprint?.os?.version,
cpuArchitecture: fingerprint?.cpu?.architecture,
agentClient: fingerprint?.ua,
},
};
const response = await userLogin({ ...data }).unwrap();
if (response?.data?.accessToken) {
storeUserInfo({ accessToken: response?.data?.accessToken });
message.success(`${response?.message}`);
if (isLoading) {
return <LoadingPage />;
}
const { role } = getUserInfo() as IJwtDecoded;
router.push(`/${role}`);
}
} catch (error: any) {
if (error?.data?.message) {
message.error(error?.data?.message);
}
}
}; `