React.js Collect logs from anywhere in your React.js application. (React >= 16)
LogsHQ.io/react can be used everywhere in your Application, Components, middlewares (ie. Saga), Server Side, Client Side, Next.js, etc.
Installation
Using NPM
Copy npm i @logshq.io/react --save
Using Yarn
Copy yarn add @logshq.io/react
If you don't have yarn installed, install it globally:
Copy npm install --global yarn
Add logs to every piece of your React application
Example of error tracking in React Component, create your logger util:
Copy // utils/logger.js
import LogshqLogger from '@logshq.io/react' ;
const logger = new LogshqLogger ({
project_id : 'SOME-PROJECT-ID' ,
api_key : 'SOME-STREAM-KEY' ,
environment : 'production' , // optional
hostname : 'auth-service' , // optional
});
export default logger;
Copy import React , { useState , useEffect } from 'react' ;
// Import the logger
import logger from '../utils/logger' ;
import axios from 'axios' ;
const MyComponent = () => {
const [ data , setData ] = useState ([]);
const fetchData = async () => {
try {
const result = await axios (
'https://some-domain.com/api/v1/search?query=myQuery' ,
);
// Success
setData ( result .data)
} catch (error) {
// Send the error itself and some additional details to help debugging properly
logger .error (error , {
component : 'MyComponent' ,
someData : {
someNestedData : 'Some Value'
}
})
}
};
useEffect (() => {
fetchData ();
} , []);
return (
< div >
< ul >
{
data .map (item => (
< li key = { item .id}>
< a href = { item .url}>{ item .title}</ a >
</ li >
))
}
</ ul >
</ div >
);
}
export default MyComponent;
You can perform search using any of the data that you have sent once the log is received:
Or, way better
You can see when and how many times the issue has occurred.
Example of sending logs from Redux Saga
Copy import logger from '../utils/logger'
export function* SagaExample () {
try {
const res = yield call ( ... )
const rawData = yield res .json ()
if ( res .status !== 200 ) {
yield put ( actions .FetchFailure (rawData));
// <= your log here
logger .error (rawData , {
method : 'SagaExample bad request'
})
return
}
yield put ( actions .FetchSuccess (rawData))
} catch (error) {
yield put ( actions .FetchFailure (error));
// <= your log here
logger .error (rawData , {
method : 'SagaExample technical error'
})
}
}
Track errors globally using React Error Boundary
You can handle errors globally using an error boundary component. An error boundary is a React component that catches JavaScript errors anywhere in its child component tree, logs those errors, and displays a fallback UI instead of the component tree that crashed. Here's an example of how you can set up a global error boundary in your React application:
Copy // utils/logger.js
import LogshqLogger from '@logshq.io/react' ;
const logger = new LogshqLogger ({
project_id : 'SOME-PROJECT-ID' ,
api_key : 'SOME-STREAM-KEY' ,
environment : 'production' , // optional
hostname : 'auth-service' , // optional
});
export default logger;
Create an error boundary component
Error boundary component catches errors and displays a fallback UI. In this example, we'll create a component called ErrorBoundary that catches errors and displays an error message to the user.
Copy // ErrorBoundary.js
import React , { Component } from 'react' ;
import logger from '../utils/logger.js'
class ErrorBoundary extends Component {
state = { hasError : false , error : null , errorInfo : null };
componentDidCatch (error , errorInfo) {
// Log the error to our remote logging infrastructure
logger .error (error , {
errorInfo : errorInfo
});
// Change the state
this .setState ({ hasError : true , error , errorInfo });
}
render () {
if ( this . state .hasError) {
return (
< div >
< h1 >Something went wrong.</ h1 >
< p >{ this . state . error .toString ()}</ p >
< p >{ this . state . errorInfo .componentStack}</ p >
</ div >
);
}
return this . props .children;
}
}
export default ErrorBoundary;
Wrap your application's root component with the ErrorBoundary component. In this example, we'll wrap the App component with the ErrorBoundary component:
Copy // app.js
import React from 'react' ;
import ErrorBoundary from './ErrorBoundary' ;
import App from './App' ;
function Root () {
return (
< ErrorBoundary >
< App />
</ ErrorBoundary >
);
}
export default Root;
That's it! Now any unhandled errors that occur in your React application will be caught by the ErrorBoundary component and can be handled as needed.
Configuration options
Option Description Required Default Details that you want to join to every log