Add LogRocket to an Angular app using ngrx

You know you get those issues from a user of your application where they kindly take the time to report the problem in detail. They outline the steps they undertook which ended with them receiving unexpected behaviour. But, though following their instructions, you can't reproduce the issue.

You then have a look at your application logs and there are no errors occurring at the time. So you decide to go through the non errors, but nothing shows up as out of the ordinary.

You try several other avenues of investigation, all fruitless.

You apologise to the user, explain you've investigated but there's nothing more you can do.

It all ends rather unsatisfactorily.

Enter LogRocket.

Note: I have no affiliation with LogRocket, I've never spoken to anyone at the company, I'm writing this for no other reason than I think it's great.

What is LogRocket

LogRocket records everything users do on your site, helping you reproduce bugs and fix issues faster.

LogRocket is the JavaScript logging and replay tool. It captures every log, network request and user session of your app. It not only records everything, but provides an experience similar to Chrome DevTools for replaying recorded sessions, showing the user's screen, network traffic, console output, etc.

There's a free pricing tear, so I decided to give it a go.

Adding LogRocket to an angular app

The steps I outline here differ from the official guide as I'm using the version 4 of @ngrx/store, which requires a different mechanism for adding middleware.

1. Create a free account at https://logrocket.com/ and take note of your application ID.

2. Add the logrocket package:

npm install --save logrocket

3. Enable allowSyntheticDefaultImports:

Add "allowSyntheticDefaultImports": true to tsconfig.json. This was required to prevent the compile error Module ''logrocket'' has no default export.

{
  "compilerOptions": {
    …
    "allowSyntheticDefaultImports": true,
    …
}

4. Initialise LogRocket in the app.component:

import LogRocket from 'logrocket';

// Initialize LogRocket with your app ID
LogRocket.init(<your_application_id>);

5. Add the @ngrx/store middleware:

import {ActionReducer} from '@ngrx/store';
import LogRocket from 'logrocket';

const reduxMiddleware = LogRocket.reduxMiddleware();

export function logrocketMiddleware(reducer): ActionReducer<any, any> {
  let currentState;
  const fakeDispatch = reduxMiddleware({
    getState: () => currentState,
  })(() => {});

  return function (state, action) {
    const newState = reducer(state, action);
    currentState = state;
    fakeDispatch(action);
    return newState;
  };
}

@NgModule({
  declarations: [AppComponent],
  imports: [
    …
    StoreModule.forRoot(reducers, {
      metaReducers: [
        logrocketMiddleware,
      ],
    }),
    …
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

That's it. Run the application and see the sessions start to be recorded.