How to get Google Analytics to work with React - reactjs

I'm trying to track each page but google only registers a view each time I click the refresh button. Not when iv'e routed to a new path. Anyone got an Idea on how to make this work?
import React, {useEffect} from 'react';
import { BrowserRouter, Switch, Route } from "react-router-dom";
import OurWork from "./ourWork/ourWork"
import Home from "./home/Home"
import Packages from "./packages/Packages"
import Contacts from "./contact/Contact"
import ReactGA from 'react-ga'
import createHistory from 'history/createBrowserHistory'
const Routes = () => {
const {
ContactPage
} = Contacts();
const history = createHistory()
history.listen(location => {
ReactGA.set({ page: location.pathname });
ReactGA.pageview(location.pathname);
});
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search)
}, [history])
return(
<BrowserRouter history={history}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/ourwork" exact component={OurWork} />
<Route path="/packages" exact component={Packages} />
<Route path="/Contact" exact component={ContactPage} />
</Switch>
</BrowserRouter>
)
}
export default Routes;

Looks like the same issue which is described here. Try to change <BrowserRouter history={history}> to <Router history={history}> and import Router from the "react-router-dom", like this:
import React, {useEffect} from 'react';
import { Router, Switch, Route } from "react-router-dom";
import OurWork from "./ourWork/ourWork"
import Home from "./home/Home"
import Packages from "./packages/Packages"
import Contacts from "./contact/Contact"
import ReactGA from 'react-ga'
import createHistory from 'history/createBrowserHistory'
const Routes = () => {
const {
ContactPage
} = Contacts();
const history = createHistory()
history.listen(location => {
ReactGA.set({ page: location.pathname });
ReactGA.pageview(location.pathname);
});
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search)
}, [history])
return(
<Router history={history}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/ourwork" exact component={OurWork} />
<Route path="/packages" exact component={Packages} />
<Route path="/Contact" exact component={ContactPage} />
</Switch>
</Router>
)
}
export default Routes;

Related

Why is Jest not rendering React Router component correctly?

Testing a router component and when I call the screen.debug() in a test after rendering, the DOM output is not what I expected. Why?
Test:
import { render, userEvent as user, screen, getByRole } from '#testing-library/react'
import { Router } from 'react-router-dom'
import { createMemoryHistory } from 'history'
import AppRouter from '../router'
test('Renders AppRouter', () => {
const history = createMemoryHistory({ initialEntries: ['/post'] })
render(() => (
<Router history={history}>
<AppRouter />
</Router>
))
screen.debug()
})
Component:
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom'
import { useState } from 'react'
import useLocalStorage from './hooks/useLocalStorage'
import * as Constants from './constants'
import Header from './layout/header/header'
import MainPage from './pages/mainPage/mainPage'
import PostPage from './pages/postPage/postPage'
import UserPage from './pages/userPage/userPage'
import LoginPage from './pages/loginPage/loginPage'
import SignupPage from './pages/signupPage/signupPage'
import NewPage from './pages/newPage/newPage'
import FeedbackPage from './pages/feedbackPage/feedbackPage'
import AdminPage from './pages/adminPage/adminPage'
import SettingPage from './pages/settingPage/settingPage'
import { WebContext } from './context/WebContext'
import Favicon from 'react-favicon'
const AppRouter = () => {
const [adminCode, setAdminCode] = useLocalStorage('admin', '')
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [page, setPage] = useState(Constants.Page.Home)
return (
<BrowserRouter>
<div role="hello">
<Favicon url={require('../public/favicon.ico')} />
<WebContext.Provider
value={{
isMenuOpen,
setIsMenuOpen,
page,
setPage,
adminCode,
setAdminCode,
}}
>
<Header />
<h1>
hello
</h1>
<Switch>
<Route component={MainPage} path="/" exact={true} />
<Route component={PostPage} path="/post/:id" />
<Route component={UserPage} path="/user" />
<Route component={LoginPage} path="/login" />
<Route component={SignupPage} path="/signup" />
<Route component={NewPage} path="/new" />
<Route component={FeedbackPage} path="/feedback" />
<Route component={AdminPage} path="/admin" />
<Route component={SettingPage} path="/setting" />
<Route component={() => <Redirect to="/" />} />
</Switch>
</WebContext.Provider>
</div>
</BrowserRouter>
)
}
export default AppRouter
Code-Trace:
EDIT
Error when not passing in a function to render:
Favicon error:
You are passing a function to the test render function when it's expecting JSX.
Remove the function definition and just pass the Router and AppRouter as JSX.
Example:
test('Renders AppRouter', () => {
const history = createMemoryHistory({ initialEntries: ['/post'] });
render(
<Router history={history}>
<AppRouter />
</Router>
);
screen.debug();
});

React Typescript Error: Invariant failed: You should not use <withRouter(App) /> outside a <Router>

I was developing an App where I use Firebase as an Authentication system of the App, an when I try to implement the routes of the app, I start to get the above title error.
I'm using withRouter funtion, to encapsulate my App component.
So the code of my App.tsx file is the following:
import React, { FC, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
Route,
Switch,
useHistory,
withRouter,
BrowserRouter as Router,
} from "react-router-dom";
import "./App.css";
import Header from "./components/sections/Header";
import SignUp from "./components/pages/SignUp";
import SignIn from "./components/pages/SignIn";
import ForgotPassword from "./components/pages/ForgotPassword";
import Homepage from "./components/pages/Homepage";
import Dashboard from "./components/pages/Dashboard";
import PrivateRoute from "./components/auth/PrivateRoute";
import PublicRoute from "./components/auth/PublicRoute";
import Loader from "./components/UI/Loader";
import firebase from "./firebase/config";
import {
getUserById,
setLoading,
setNeedVerification,
} from "./store/actions/authActions";
import { RootState } from "./store";
const App: FC = () => {
const dispatch = useDispatch();
const { loading } = useSelector((state: RootState) => state.auth);
let history = useHistory();
// Check if user exists
// App.tsx
useEffect(() => {
dispatch(setLoading(true));
const unsubscribe = firebase.auth().onAuthStateChanged(async (user) => {
if (user) {
await dispatch(getUserById(user.uid));
if (user.emailVerified) {
history.push("/homepage");
} else {
history.push("/signin");
dispatch(setNeedVerification());
}
}
dispatch(setLoading(false));
});
return () => {
unsubscribe();
};
});
if (loading) {
return <Loader />;
}
function Routes() {
return (
<Switch>
<PublicRoute path="/signup" component={SignUp} exact />
<PublicRoute path="/signin" component={SignIn} exact />
<PublicRoute path="/forgot-password" component={ForgotPassword} exact />
<PrivateRoute path="/dashboard" component={Dashboard} exact />
<PublicRoute path="/homepage" component={Homepage} exact />
</Switch>
);
}
return (
<Router>
<Header />
<Routes />
</Router>
);
};
export default withRouter(App);
`So I think that have to be realated with the configuration of Route library into the main component of the app.
What I missing??
Take thankss in advance !
App is the component rendering the Router so App itself can't use anything that requires a Router context higher up in the React tree.
The solution is to move the Router higher in the React tree, i.e. wrap App in the Router. Once App is being rendered by a Router and since you are using the useHistory hook there will be no need to decorate with the withRouter HOC.
App
const App: FC = () => {
...
function Routes() {
return (
<Switch>
<PublicRoute path="/signup" component={SignUp} exact />
<PublicRoute path="/signin" component={SignIn} exact />
<PublicRoute path="/forgot-password" component={ForgotPassword} exact />
<PrivateRoute path="/dashboard" component={Dashboard} exact />
<PublicRoute path="/homepage" component={Homepage} exact />
</Switch>
);
}
return (
<>
<Header />
<Routes />
</>
);
};
export default App;
index where App is rendered.
import { BrowserRouter as Router } from "react-router-dom";
import App from '../App';
...
<Router>
<App />
</Router>

React returning blank page when accessed directly from browser address bar

This is My App.js file where all the routes is defined.
import React, { useState, useEffect, createContext } from 'react'
import { Route, Switch } from 'react-router-dom'
import Posts from './components/Posts'
import Login from './components/Login'
import { Home } from './components/Home'
import './assets/css/style.css'
import Layout from './components/Layout'
import Account from './components/Account'
import AppliedJobs from './components/AppliedJobs'
import About from './components/About'
import Contact from './components/Contact'
import { MultiStepForm } from './components/MultiStepForm'
import ForgotPassword from './components/ForgotPassword'
import ResetPassword from './components/ResetPassword'
import PrivacyPolicy from './components/PrivacyPolicy'
import { toast } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
export const userContext = createContext()
toast.configure()
const App = (props) =>{
const [auth, setAuth] = useState();
useEffect(() => {
if (sessionStorage.getItem('token') !== null) {
setAuth(true);
} else {
setAuth(false);
}
}, []);
console.log('Auth Status',auth)
let routes = (
<Switch>
<Route exact path='/' component={()=> <Home auth={auth} />}/>
<Route exact path='/job/:id' component={Posts}/>
<Route exact path='/login' component={() => <Login setAuth={setAuth}/>}/>
<Route exact path='/accout' component={Account}/>
<Route exact path='/appliedjobs' component={AppliedJobs}/>
<Route exact path='/about' component={()=> <About/>}/>
<Route exact path='/contact' component={Contact}/>
<Route exact path='/Registration' component={MultiStepForm}/>
<Route exact path='/forgot' component={ForgotPassword}/>
<Route exact path='/reset/:id' component={ResetPassword}/>
<Route exact path='/privacypolicy' component={PrivacyPolicy}/>
</Switch>
)
return(
<div>
<Layout auth={auth} >{routes}</Layout>
</div>
)
}
export default App
When I try to access any route from direct URL, it shows me Blank Page. I have did tones of research on this but any solution didnt worked for me..............................................................
Check whether you are authenticating setAuth(true); and passing props properly in Layout component
The Problem is solved by just changing the <Switch> to <hashRouter>.

React-Redux-Saga history.push is updating url, but not loading the component

I am trying to redirect from saga after a password change, and history.push() is just updating the URL not loading the component
Hisotry.js
import { createBrowserHistory as history } from "history";
export default history({
bforceRefresh: true,
});
App.js
import React from "react";
import { BrowserRouter } from "react-router-dom";
import history from "../../helpers/history";
import Navigation from "../Navigation";
import AppAuthRouter from "../Navigation/routes";
const App = () => (
<BrowserRouter history={history}>
<Navigation app_auth_router={AppAuthRouter} />
</BrowserRouter>
);
export default App;
AppAuthRouter.js
import * as ROUTES from "../../constants/routes";
import ProtectedRoute from "./protectedroute";
const AppAuthRouter = () => (
<Switch>
<ProtectedRoute path="/admin" component={AdminPage} />
<ProtectedRoute
path="/updatepwd"
component={PasswordChangePage}
/>
<ProtectedRoute path="/welcome" component={WelcomePage} />
<Route path={"/signup} component={SignUpPage} />
<Route path={"/signin} component={SignInPage} />
<Redirect path="*" to={{ pathname:"/signin"}} />
</Switch>
);
export default AppAuthRouter;
Saga.js
import history from "../helpers/history";
function* passwordChangeSaga({ creds }) {
try {
yield put(alertSuccess("Password has been changed successfully"));
history.push("/welcome");
} catch (gerror) {
const error = googleError2Error(gerror);
}
}

React Router stop working after upgrade React

I upgrade React from v16.0.0 to the last version to use Hook, after the upgrade, React Router stop working.
This is the AppRoute code:
import React from 'react';
import { Router, Route, Switch } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
import DashboardPage from '../components/DashboardPage';
import HelpPage from '../components/HelpPage';
import NotFoundPage from '../components/NotFoundPage';
import LoginPage from '../components/LoginPage';
import PrivateRoute from './PrivateRoute';
import PublicRoute from './PublicRoute';
export const history = createHistory();
const AppRouter = () => (
<Router history={history}>
<div>
<Switch>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute path="/dashboard" component={DashboardPage}/>
<Route path="/help" component={HelpPage} />
<Route component={NotFoundPage} />
</Switch>
</div>
</Router>
);
export default AppRouter;
I'm getting:
Output
thank you very much!
Ori
The Router Component in react-router-dom is actually called BrowserRouter not Router , so change Router import and Tag to BrowserRouter or Just Provide an alias and it should work without changing the tag
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
and instead of createHistory use createBrowserHistory
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
Refrence here
CodeSandbox here
Try not combining logic with UI
// ...code...
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// ...code...
const AppRouter = () => {
const [loggedIn, setLoggedIn] = useState(false)
return (
<Router>
<Switch>
{
!loggedIn
? <Route exact path="/" component={LoginPage} />
: <Route exact path="/dashboard" component={DashboardPage}/>
}
<Route exact path="/help" component={HelpPage} />
<Route component={NotFoundPage} />
</Switch>
</Router>
);
}

Resources