Closed estebandlp closed 3 years ago
same here problem with ssr
bump
There are many solutions in issue #53. Instead of doing a direct import like import ReactPixel from 'react-facebook-pixel
, you need to dynamically import it:
useEffect(() => {
import('react-facebook-pixel')
.then(module => module.default)
.then(ReactPixel => {
ReactPixel.init('your-pixel-code)
ReactPixel.pageView()
})
}, []
@superapplejuice While it may be true that there are workarounds, it would be extremely easy for this module to make itself SSR friendly (as it already was before v1.0). There can be build system side effects or other situations where dynamic imports won't necessarily work (or at least are far more complicated). It would be such an easy fix to make the module a no-op if a browser environment is not available.
Since a user tracking system like pixel is by definition "client-side" there is no point in making developers have to jump through hoops to force the module to not load on the server.
I'm more concerned that @zsajjad hasn't weighed in on the issue yet. Of course we can always fork the module since it would be an easy fix, but it is highly preferable for the original maintainers (who may have other features/enhancements in the works) to implement a fix that would make the library much easier to use. Maybe @zsajjad is busy; I know maintaining open source libraries can be a burden. I'm certainly thankful for the code--just hoping we can get it back to being SSR friendly.
Hi sincere apologies for the delayed response. I would highly appreciate any PR or good suggestions on fixing this issue
@zsajjad Thanks for the response. Can you explain why the change was made in eb70fa4 (patch for existing integration)? This is the cause of the SSR issues:
let initialized = !!window.fbq;
Is there a specific reason why the initialized variable needs to know if the fbq object exists before the init
method is called?
It would seem like a pretty easy fix would simply be to change that line to:
let initialized = (typeof window !== 'undefined') && !!window.fbq;
I see that @mimcz appears to have already submitted a pull request with essentially this very change.
I have merged that MR. Will release the updated version in a while. Thanks for taking this up.
Hi. When will this be released to npmjs.com? Currently, it is version 1.0.3 there and was last published 5 months ago.
New version is live
@zsajjad This still fails for Gatsby SSR build. Using latest version 1.0.4.
WebpackError: ReferenceError: window is not defined
- fb-pixel.js:1
node_modules/react-facebook-pixel/dist/fb-pixel.js:1:201
How to reproduce:
npx gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
cd my-default-starter
npm i react-facebook-pixel
# + react-facebook-pixel@1.0.4
npm i prop-types # due Can't resolve 'prop-types' in ... 'gatsby-react-router-scroll'
# 'npx gatsby build' still works here
# add import for react-facebook-pixel to e.g. src/pages/index.js
npx gatsby build #fails now
@iaarnio it appears you are using the pre-built module in the dist
folder that for some reason hasn't been updated since v1.0.1. I haven't tested the new version yet in my setup so I can't comment yet on whether the issue still appears on my side.
Edited - see post below
@zsajjad I've tested the new release and have the same problem @iaarnio has. Even when bundling with webpack the library is using the dist
folder that has been committed to the repo (which is still on v1.0.1).
~I think the main
parameter in package.json
should point to src/index.js
.~ This would allow bundlers like webpack to use the actual source files when building a client app. Including a UMD build in a dist folder is fine, but that is really only for users who don't build their apps using bundlers like webpack, and these users should specify the full path to the file. If the main
parameter points to a pre-built dist file then we lose the benefits of webpack processing when building the app client side.
I've dug into this a bit more and I think what is missing here is the transpiled source (usually put in a lib
folder). Since we're in a transitional period with ES source code in the context of package managers a fairly conventional process is to provide the raw (untranspiled) code in src
, a transpiled (ES5) version in lib
, and a UMD build in dist
. The package.json main
field in this scenario points to the transpiled version in lib
allowing bundlers like webpack to access the non-minified transpiled code. Those who need a UMD build can access it directly via the dist
folder.
When I get a bit of free time I'll submit a PR that adds the lib
generation, changes the main
field, and also adds a prepare
script for use before publishing to NPM that calls the build scripts.
Edit - I've now sent a PR with the relevant fixes
import ReactPixel from 'react-facebook-pixel';
Error: window is not defined
why its not working with next js in the global js file or anywhere else also ? previously it was working with react current version :^1.0.4 (react-facebook-fixel);
I had this same problem.
"use client";
import React, { useEffect } from "react";
import { usePathname, useSearchParams } from "next/navigation";
import ReactPixel from 'react-facebook-pixel';
export const FacebookPixelEvents: React.FC = () => {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
import("react-facebook-pixel")
.then((x) => x.default)
.then((ReactPixel) => {
ReactPixel.init(`${process.env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID}`);
ReactPixel.pageView();
});
ReactPixel.init(`${process.env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID}`);
ReactPixel.pageView();
}, [pathname, searchParams]);
return null;
};
export const fbPixelAddToCart = async () => {
ReactPixel.fbq('track', 'AddToCart');
}
export const fbPixelInitiateCheckout = async () => {
ReactPixel.fbq('track', 'InitiateCheckout');
}
This line was throwing the error: "window is not defined":
import ReactPixel from 'react-facebook-pixel';
So i've made some conditional imports:
"use client";
import React, { useEffect, useState } from "react";
import { usePathname, useSearchParams } from "next/navigation";
let ReactPixel: any = null;
if (typeof window !== 'undefined') {
import('react-facebook-pixel')
.then((x) => x.default)
.then((currReactPixel) => {
ReactPixel = currReactPixel;
})
}
export const FacebookPixelEvents: React.FC = () => {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if(!ReactPixel) {
import('react-facebook-pixel')
.then((x) => x.default)
.then((currReactPixel) => {
ReactPixel = currReactPixel;
})
ReactPixel.init(`${process.env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID}`);
ReactPixel.pageView();
} else {
ReactPixel.init(`${process.env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID}`);
ReactPixel.pageView();
}
}, [pathname, searchParams]);
return null;
};
export const fbPixelAddToCart = async () => {
if(ReactPixel) ReactPixel.fbq('track', 'AddToCart');
}
export const fbPixelInitiateCheckout = async () => {
if(ReactPixel) ReactPixel.fbq('track', 'InitiateCheckout');
}
Do a conditional import only when the window type is not undefined, and on the first render I had the problem that the React pixel was sometimes null, so in useEffect I also did a conditional import. (pedilo)
When I install and try to use the library with Next.js, and Init the Pixel, then I have the following error: "ReferenceError: window is not defined"
This error is in fb-pixel.js and is fixed adding: if (typeof window !== "undefined") at the beginning of the script.
This modification could generate another issue?