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

npm i @logshq.io/react --save

Using Yarn

yarn add @logshq.io/react

If you don't have yarn installed, install it globally:

npm install --global yarn

Add logs to every piece of your React application

Example of error tracking in React Component, create your logger util:

// 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;
component.js
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

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:

  1. Create your logger util

// 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;
  1. 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.

// 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;
  1. Wrap your application's root component with the ErrorBoundary component. In this example, we'll wrap the App component with the ErrorBoundary component:

// 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

OptionDescriptionRequiredDefault

project_id

Your project ID

Yes

api_key

Your Stream key

Yes

hostname

Project hostname

No

null

environment

Project environment

No

null

silent

Disable sending logs

No

false

defaultMeta

Details that you want to join to every log

No

Empty object: {}

Last updated