Categories
Tech Industry

The WFHpocalypse Part 1: Thoughts on Remote Work

Since the global quarantine working-from-home, or remote work, seems to be everything anyone can talk about. 

About 15 years ago when I started my career, software engineers were a rare, abstract breed of professionals. People knew of this profession, talked about it, but few had met someone who actually worked day-to-day writing code.

In that day (around 2005), the term ‘colocating’ became a thing.  Colocating basically means, albeit confusing, when people work in the same office. So in other words, working onsite. (In the context of a computer or server that is co-located, and I realize I’m dating myself by even mentioning physical servers— yes, actual machines— colocate meant to host your physical server on-premises with your company or in an existing data center with other physical servers you also operate.)

In my experience, even by 2008 it was regular and normal for more non-tech employees to work from home (or “WFH” as is abbreviated) at least one day a week. Jobs were routinely advertised or negotiated with a certain number of ‘WFH’ days. Engineers worked from home even more, many working remote all of the time. 

Then around 2013 some of the larger tech companies started to crack down on their employees working remotely. Marissa Meyer, the new head of Yahoo, famously set a no-work-from-home policy, vexing many of the Yahoo employees with families who had felt they had been hired under the auspices of workplace flexibility.

Years before this, a manager told me that they had no shortage of mediocre people who would show up onsite and work 9-5, but virtually no candidates who would work a regular 9-5 job and were exceptional. The exceptional candidates, she explained, all had demands—workplace flexibility chief among them.

My own experience has born this out too: The best developers I ever worked with were ones who worked remotely.

In fact, two that come to mind worked for companies in New York City — where I was an ‘onsite’ employee on the team — and did all of their work entirely remotely. While both of these people came to New York to visit— maybe once every six months — neither preferred to move to city that was more expensive than where they already had a good living.

Both of these guys were rockstars, and I mean rockstars in the truly respect-worthy sense. You’d have meetings with them and the next day they’d already been whipping up some sample code. They outperformed every member of the large team consistently week after week.

Except one time. Stan (one of these exceptional developers) and Peter (the product owner), and I built a system. It was a management workflow for an internal agency. In the agency, the projects had a natural step-by-step flow from concept to ideation to wire framing to production to delivery. Sounds straightforward enough.

Peter the product owner had written a complicated state diagram that showed while the normal set of steps was 1, 2, 3, 4, 5. Sometimes a project could go from step 5 back to 2, or from step 3 to step 2. His diagram had a number of complex transitions based on what the stakeholders had told him upfront about their needs.

So Peter, shows this to Stan (who happened to be my boss at the time) who immediately solves it using every developer’s favorite pattern: a state machine.

The state machine implementation was beautiful. It had gated locking mechanisms that allowed transitions only through the specified transition steps. We deployed it; everyone loved it. It was the first time the agency has had a custom workflow built around their needs.

“This thing is great,” someone tells me as feedback. “But why can’t I go from step 4 to step 2? Why must I advance to step 5 before going back to 2?”

Peter, me, and Stan have a meeting. “They love this product but we don’t need all these rules blocking people from just putting the project into the state they want it to be it.” Dammit, Stan thinks, then why did you draw me a fancy chart that said you did up-front?

Whether this was a failure of product development or imagination I can’t say, but it always struck me as funny that here I was, much more junior to Stan’s experience in Ruby on Rails, and I had an inkling that the fancy state machine he built wasn’t going to be as useful as he thought. (Of course, he was my boss, and obviously it is what ‘they’ had asked for, but I still pictured the agency’s chaotic workflow and thought to myself, they’re going to want to change the states back and forth and back and forth, why are we building this state machine that locks them into specific transitions? I didn’t bring up my objections to Stan at the time.)

Not only had he overbuilt something, but he’d in fact built something that was a hinderance to the end user (exactly what you don’t want in good software). In our case, our user base was small and forgiving (only the people in the company), and so the impact was minimal. We removed the transition locks (but still kept the underlying ‘state machine’ coding pattern) so that a project could be moved from any state to any state. All things considered, nobody creatives were harmed in the making of the software and the cost of being wrong was low.

But building that state machine wasn’t a small bit of coding. Not months of wasted work, but it probably was weeks of wasted work.

It always struck me that Stan, a bit of a left-brained nerd, always seemed to related to the code better than he could relate to the people.

And therein lies the heart of the tension between the ‘onsite’ world and the ‘remote work’ world: Are you relating on an empathic level to the company’s needs or are you relating on an technical level?

I’ve heard all sides of the onsite vs. remote-worker divide. Since it’s such a controversial topic, I’ll list just some of what I’ve heard about the benefits of letting your workers work remotely: 

1) As a company, you can have access to a much more significant pool of talent

2) Your workforce is more likely to work harder

3) You can distribute workers at different times to allow for asynchronous work to be done— for example, an engineer codes a feature in afternoon and someone else does QA on that feature in the evening. (In a traditional onsite workplace, your features won’t get QAed until the following day when people come back into work.)

4) Workers can live somewhere significantly cheaper than the expensive tech hubs of San Francisco or New York City. While many people think the cost living difference might be a factor of 50%, I estimate the true cost of living difference, after taxes, between an expensive city like New York and the mid-west is probably 400% (that is, it’s 4 times more expensive to live a “city lifestyle” in an expensive city than it is to live “normal lifestyle” anywhere else.)

5) Offices are distracting and not conducice to concentraion. In their book Remote,  Jason Fried and David Heinemeier Hansson ask

If you ask people where they go when they really need to get work done, very few will responde ‘the office.’ If they do say the office, they’ll include a qualifier such as “super early in the morning before anyone gets in” or “I stay late at night after everyone’s left” or “I sneak in on the weekend.’

I’ve seen both sides of this coin. On the onsite side, I’ve done onsite pairing, product development, white boarding, led and participated in onsite meetings, done mentoring of junior developers face-to-face, and also been the coder with headphones on at his desk (if you don’t know, when an engineer wears headphones you can think of it like he or she is wearing a “don’t talk to me right now” sign)

I worked remotely for years as a consultant, and I “worked from home” on and off though many jobs in New York City too.

I am ambivalent about the debate: one the one hand, I have found onsite work to be stimulating, connecting, and effective, especially when you have a strong team (one that makes you want to come in every day.) I’ve also found onsite work to be draining, exhausting, and, worst of all, distracting. How can both of these things be true?

To be effective at what we do, developers need something that we call ‘flow.’ For laymen, thinking about the last time you wrote something— something difficult. Maybe a paper for school or a presentation that required a lot of writing. Let’s say you sit and start writing. At first, your attention is easily diverted. What you’re going to have for lunch, what your wife said to you yesterday, the sound of the ticking clock. You know you aren’t concentrating, so you concentrate harder. After about 15-20 minutes, you are typing sentences and they seem to be flowing out of you. Then someone comes in the door and asks you a question. You look up, “Sorry, what did you say?” Half of your brain is still writing, but it was just jarred into something else by the event that distracted you.

Programming is like this every single day, and the need for focus is even more dramatic than most professions. Non-programers typically underestimate the significance of flow in software development. 

Product development, which is a constant back-and-forth with stakeholders, is something that dramatically benefits from people being in the same place. If you sit with the people you are building software for you are more likely to connect with them on an empathic level, a key component to being a great product owner. As the state machine example with Stan demonstrates, sometimes if the only things you interact with are computers you begin to identify more with the computers than the people. (That’s not a good thing.)

Self-starters remote employees like Stan and Thomas (and yours truly, often) — partly because they have the privilege of working remotely— are focused on results precisely because nobody is looking over our shoulder or clocking our hours.

The Coronavirus is a paradigm shifting event to the WFH vs. onsite worker debate: Everybody has to stay home during the quarantine. Companies and teams that have never worked remotely are suddenly forced into this situation. I can only imagine CEOs and Human Resources people who have looked down on remote workers judgmentally— which sadly I fear are the majority— are going to loose their shit.

 

In the next post I’ll explore working onsite work, how it has changed, where it shines and what its pitfalls are. 

Be sure to LIKE & FOLLOW for Part 2.

Categories
Tech Industry

Working from WeWork During a Pandemic

I sit here as the World Health Organization declared last night a global pandemic due to COVID-19, and all everyone can seem to think or talk about is how scary this virus is. Nearly universally, as universities and events were canceled this week, workers across America began to work from home.

Zoom Conferencing, global platform for video-conferencing, arguably, the company to have defined the video platform industry, is up on the stock market today, as a sign of the times:

  • Loading stock data...

Everywhere I turn it seems people are freaking out: scared to ride the subway, travel is down, stocking up on supplies and food, and talking about working from home.

In a cafe that I went to yesterday — normally a quiet haven of distraction-free concentration — a woman sat with her laptop on video conference. “Is this working? Can you hear me? We’re all video conferencing, then!” she said in her slightly British accent. Amateur, I thought, as I put on my headphones so as to maintain some semblance of separation between me and the talk of the pandemic.

Although I couldn’t help but be struck by one obvious paradoxical fact: The cafe I was sitting in posed no less of a risk than a traditional workplace. In some regards, with that many people touching tables, touching counters, etc, there isn’t any reason to think that the virus won’t spread just as easily if we all work from public cafés.

Here at my WeWork office earlier this week, people were talking about adjusting to this ‘new normal.’

“I heard they aren’t testing here in New York,” I overhear someone say. “I heard they are but they don’t have enough test kits,” someone else responds. Mostly, it’s the fear of not knowing that seems to be the driving force of stress.

The small coffee shop where I get my coffee (not the café mentioned above) had a sign today that read: “Out of an abundance of caution due to COVID-19, we are not doing ‘bring your own’ container or using ceramic mugs for the time being. Thank you for understanding.” Of course, I think, the customer touches the reusable to-go cup (like those metal mugs people use to reduce waste), the barista touches the container, the virus spreads to the barista’s hands, they give it back to the customer and then go on to spread the virus to the next customer’s order, and the next.

And so the small modifications to our lifestyle and adjustment to this ‘new normal’ begin.

As I sit and write this from WeWork DUMBO (in Brooklyn) it strikes me how ironic it is that in fact, working from WeWork is probably rather safe right now. Why? Well, for one thing, there’s nobody here. Office after office has shut down, people are working from home. This place feels like a ghost town.

Furthermore, people who work at WeWork tend to be adult professionals who act in a highly professional way:

  1. Of course everybody washes their hands every time we come in or go out.
  2. I get to walk here, which helps me avoid the germ-infested subway system of New York City.
  3. The entryways have contactless scanners I don’t even need to touch my card to the turnstiles (I can just wave it over).
  4. I touch only the elevator buttons and can even do this with my elbow.
  5. I wash my hands immediately upon walking in
  6. Every surface is washed down, now (as I’m told by general announcement) multiple times a day.

Hospitals used to be a place where it was presumed that you would go to die as people generally went into hospitals and didn’t come out. Then doctors and nurses started washing their hands and people started coming home from the hospital.

(In 1846, Ignaz Semmelweis, a Hungarian doctor noticed something interesting about two wards: In the maternity ward run by students and doctors, women giving birth were more likely to develop a fever and die than the women in another maternity ward right next door that was run by midwives. He noticed that doctors and nurses often visited expecting mothers after performing an autopsy on a dead person. As a result, Semmelweis mandated handwashing with chlorine for doctors. Suddenly, new mothers stopped dying at the rates seen before.)

Today, doctors and nurses who work in hospitals will tell you that they wash their hands not to protect themselves from disease, but (largely) to protect their patients. The biggest risk is not from a doctor or nurse who is infected, but from passing germs from patient-to-patient as they make their “rounds.”

That’s why the medical profession has always said (and keeps saying): wash your hands!

The truth is, there’s a lot about COVID-19 that we still just don’t know. Panic is a manifestation of the threat to our egos. It’s a normal reaction, but the stress it causes is useless. Whether you are working from home, a café, or an abandoned (and probably septic) WeWork, there’s nothing to support the idea that just changing our work location, in fact, puts you in any less risk. Washing your hands, not touching things unnecessarily, avoiding travel, and keeping a strong immune system are probably the most effective things for you to put your energy into.

Honestly, for myself, I think the WeWork is the safest bet today.

Categories
Humor

Some Humor

Categories
Programming

Essential React Packages of Early 2020 ( Do not develop without )

The most essential Node packages to set up your React app today.

(This article was written in the context of React versions 16.9, 16.10, and 16.11 in late 2019/early 2020)

Absolutely Standard (you should install by default):

• styled-components

For creating styles inside of your components. 

prop-types

prop-types is used for validating the properties are what they are supposed to be. This is invaluable for speed in development. In a nutshell, you should get used to the idea of declaring what the valid types for your properties are (string, array, number, etc)

• @dr-kobros/react-webfont-loader

For loading Google fonts. Want your website to look pretty and unique? Go choose a Google font.

• bootstrap, reactstrap

For installing and using Bootstrap, the world’s most popular CSS framework. 

For Bigger Apps: 

• isomorphic-fetch

This is what you need to make Ajax calls to a remote server. 

• react-redux, react-thunk, thunk

You will need react and thunk if you want to create a Redux tree of data. You will have to learn how to do fun things like mapStateToProps and mapDispatchToProps, and then you will have a giant data tree that will be mapped to your react components. 

For feature detection:

• react-use

This magic tool can detect anything your user’s browser is capable of. 

• query-string

Query string will check those query parameters (like ?search or ?utm_campaign, etc) to let you grab them from the browser’s URL. 

• react-helmet
You use React helmet if you want to set the page’s HEAD tags, for example, if you want unique meta or content tags to be generated depending on what is on the page.

For Testing:

@testing-library/dom, @testing-library/jest-dom, @testing-library/react

With these you do fun things like unit testing, watching all your specs as you develop, and run a coverage report of how many lines of code you have covered. 

cypress

This is what you use if you want to integration testing. You’ll note that Cypress is written in jQuery, ironically, because you aren’t supposed to use jQuery with React.

• deep-freeze

This package makes sure that your pure functions return with no side effects and without mutating the original objects

• enzyme and enzyme-adapter-react-16 (for React 16)

Categories
Tech Industry

Queens JS (4 Apr 2020)

A photograph on the backdrop of coronavirus panick throughout the city.

Angus Grieve-Smith (@grvsmth) treated us to a display of how to audio interfaces using native web controls, appropriately titled “Web Audio With Javascript” Their website is grieve-smith.com

Angus shows how to use native Javascript to build an audio recorder.

Peter Karp talked about Pydantic, a python validation tool. He compared it to marshmallow, a tool he says is outdated and was used for serialization, validation, and typing in JSON manipulation.

Peter Karp talks Pydantic

And finally, Tracy Hinds (@HackyGoLucky) talked about conflict resolution on software development teams.

Categories
Programming

Something About Refs

React’s Virtual DOM arguably revolutionized web development. In short: React will keep a copy of the DOM in its own memory space. When you make updates, for example, several updates to component state, the React will manipulate the Virtual DOM first, performing all of the mutations on it in succession. Once all of your logic has run, React knows how to compare the Virtual DOM to the real DOM, and then it makes small, isolated updates one-by-one, only changing the least amount necessary.

Why does it do this? Well, for one thing, when the browser performs DOM operations it is famously slow at doing so, that is non-performant when many updates are happening. If each mutation of the DOM was done in the browser, you couldn’t achieve the fast effects you can with React.

You’ll note then that the objects you code in React, then, don’t expose direct access to the DOM elements. This is a good thing, because it means that to change the DOM you must always go through the React re-render cycle when you want to change your DOM.

Most of the time, this can get you most of what you need doing. But occasionally, if you need to access DOM elements to inspect them, you’ll want to use a feature of React called React Refs.

Other cases of using Refs is to manage text highlighting, managing focus, and media playback. Refs are also used for some advanced purposes too, like managing interactions with 3rd parties and multistep form state.

Today I will explore three patterns for using Refs in React: 1) A basic Ref implementation, 2) A forwarded Ref, that is a ref that has been sent to another component, and 3) A forwarded Ref used within a Styled Components setup.

Remember, your Ref will simply point to the DOM elements. What’s important here to keep in mind is that you 1) first need to create your ref, 2) then assign it to a component using ref= , and 3) let React maintain the Ref for you during the rendering.

Example #1 — Basic Usage

First, you need to create a Ref object. You do this before your component is rendered using React.createRef()

First let’s start with the most basic React component. (To see this, edit your App.js file and remove the default content and add <ThingOne />)

// src/thing_one.js

import React from 'react'

class ThingOne extends React.Component{
  constructor(props) {
    super(props)
    this.ref1 = React.createRef()
  }
  
  render() {
    return (
      <div>
        
      </div>
    )
  }
}

export default ThingOne

Notice that in the constructor, we create the Ref using this.ref1 = React.createRef(). At this point, if you examine your object, you will see something interestingly empty:

Notice that your variable now holds an object with a single key, current, that points to nothing (null).

Now, let’s add an input checkbox and also tell React to use this ref (ref1) for that input checkbox.

import React from 'react'

class ThingOne extends React.Component{
  constructor(props) {
    super(props)
    this.ref1 = React.createRef()
  }
  render() {
    return (
      <div>
        this is an experiment into forwarded refs
        <br />
        Please check this box:  
        <input type={"checkbox"} ref={this.ref1} />
      </div>
    )
  }
}

export default ThingOne

We use this Ref (ref1) in the render method, when we call

<input type={"checkbox"} ref={this.ref1} />

Here, we’re telling React when it renders the dom, a reference will be stored back onto the value in the current slot in our Ref.

If you examine the Ref after React has rendered, you get something different:

Now, the Ref’s current value is a reference to the DOM element. That means that it can be treated like a “native DOM element” because it is one.

Finally, in our little baby example, we’ll attach an onClick handler to the boxChecked handler.

import React from 'react'

class ThingOne extends React.Component{
  constructor(props) {
    super(props)
    this.ref1 = React.createRef()

    // if you don't bind your method then boxChecked will be called
    // without `this` in scope
    this.boxChecked = this.boxChecked.bind(this)
  }
  boxChecked(event) {
    const dom_elem = this.ref1.current
    const is_checked = dom_elem.checked
    alert("This box is now " + (is_checked ? 'CHECKED' : 'UNCHECKED'))
  }

  render() {
    return (
      <div>
        this is an experiment into forwarded refs
        <br />
        Please check this box:  
        <input type={"checkbox"} ref={this.ref1} onClick={this.boxChecked}  />
      </div>
    )
  }
}

export default ThingOne

Be sure to bind it to the this object (because, err.. javascript) in the constructor, and Bob’s your uncle… once clicked, this.ref1.current now returns {current: input} as you see above. As you can see from the code in boxChecked, you can pull the DOM element out from this.ref1.current and then examine it using native HTML properties (.clicked is implemented in the browser and is a native DOM element property.)

You can see the full code for this example here.

Example 2 — With Ref Forwarding

Now it’s time to go down the rabbit hole a little deeper. And with ref forwarding, we really are traveling down a rabbit hole.
Let’s stay we want to nest ThingTwo inside of ThingOne, but be able to look at the ref for ThingTwo from code inside of ThingOne.

Let’s say we try something like this

// src/thing_one.js

import React from 'react'
import ThingTwo from './thing_two'

class ThingOne extends React.Component{
constructor(props) {
super(props)
this.ref1 = React.createRef()

// if you don't bind your method then boxChecked will be called
// without `this` in scope
this.boxChecked = this.boxChecked.bind(this)
}
boxChecked(event) {
const dom_elem = this.ref1.current
alert("ThingTwo is " + dom_elem.getBoundingClientRect())
}

render() {
return (
<div style={{position: 'relative', border: 'solid 1px green'}}>
this is an experiment into forwarded refs
<br />
Please <button onClick={this.boxChecked} type="button" > click here </button>

<ThingTwo ref={this.ref1}/>
</div>
)
}
}

export default ThingOne

// src/thing_two.js

import React from 'react'

class ThingTwo extends React.Component{

render() {
return (
<div style={{position: 'relative', top: 0, left: 0, border: 'solid 1px red'}}>
This is thing Two
</div>
)
}
}

export default ThingTwo

Warning: The above code doesn’t actually work!

It makes sense that we might think we can pass a ref as a prop from one component to another. However, because of how React passes props around, this doesn’t actually work. Moreso, it actually produces no error message or indication to the developer that this is wrong. But here’s how you know it’s wrong: If you examine the ref once the UI is rendered, you get this wrong result:

If you see the name of the Component, something is wrong. it won’t work and your ref will not be usable. What’s wrong here is that you need to forward your ref from one component to another.

Interestingly, the code in thing_one.js doesn’t change — you’re still going to pass the ref down to ThingTwo via the props.

However, for ThingTwo, you need to wrap ThingTwo’s entire implementation in React.forwardRef. This utility method will take a function and will call that function with two arguments: the props passed and the ref passed, but it will allow you to pipe the ref into ThingTwo like so:

import React from 'react'

class ThingTwo extends React.Component{
  render() {
    const {selfRef} = this.props

    return (
      <div ref={selfRef} style={{position: 'relative', top: 0, left: 0, border: 'solid 1px red'}}>
         This is thing Two
      </div>
    )
  }
}

export default React.forwardRef((props, ref) => <ThingTwo {...props} selfRef={ref}  />)

Many examples online use a pattern like ref={ref} but I personally find this confusing for demonstration. What is happening is that one variable name exists in the ForwadedRef constructor, and a distinct variable also named ref then also exists inside your component, they just happen to both be called ‘ref.’ To eliminate the confusion, I named the ref that ThingTwo receives selfRef, indicating that this variable is only ever used as the reference to DOM element that maps to the component (to ‘itself’). You can pick any variable names you want, but this example demonstrates that the variable occupies a distinct namespace in ThingTwo.

Now, if you examine your ref after rendering, it looks like so:

Note that in some cases your DOM element object looks slightly different. For example, if React renders multiple of the same component, it will keep letter-based class names on your objects (it does this as its internal mapping to the DOM).

Here’s an example from a different app (you aren’t seeing the code for this). In this case, my component has a built-in class for logo-container and the strange-looking characters that make up the other classes are correct.

The example code for example #2 can be found here.

Example 3 — With Ref Forwarding in a Styled Component

Forwarding refs is slightly tricky. Once you get the hang of it, it makes sense. Always remember that the receiving component must be wrapped in the forwarder. The final pattern to show you here is how a ForwardedRef can be used with Styled Components.

This example is just like #2, except that ThingTwo uses a StyledThingTwo to display itself

import React from 'react'
import styled from 'styled-components'


const StyledThingTwo = styled.div`
  position: relative;
  top: 0;
  left: 0; 
  border: solid 1px red;
`

class ThingTwo extends React.Component{
  render() {
    const {selfRef} = this.props

    return (
      <StyledThingTwo ref={selfRef} >
        This is thing Two
      </StyledThingTwo>
    )
  }
}

export default React.forwardRef((props, ref) => <ThingTwo {...props} selfRef={ref}  />)

You will note that because StyledThingTwo is a functional styled component, it doesn’t need its own forwarded ref wrapper. Only the ThingTwo needs to be wrapped in the forwardRef call.

Categories
Tech Industry

Brooklyn JS #75 (13 Jan 2020)

Thomas Bery told us about his project to build jambuds.club, a social listening platform he has been working on as passion project.

Fil Zembowicz, who says he runs a company called FormSort, gave a talk called “Grappling with Higher Powers”. @fzembow on twitter.

Jessie Wu talked to us about building automated phone systems using Amazon connect with Amazon Lex. She pulled of a successful live demo of Hotling bling.

Travis Fisher then gave us some opinions about open source.

Finally, Tom Luttg finished off the evening with a talk called “Keeping Neural Networks Weird”


The musical guest for the evening was Jake from Baby Got Backtalk

TODO: look up saasify.sh

Apple Airport Express Base Station models A1088, A1264, and A1392

If you own an Apple Airport Express Base station model number A1088 (sold 2004-2008), it will no longer update with Apple Airport Utility 5.7.

If you have a later version A1264 (sold 2008 to 2012) or (sold 2012 to 2018) it will continue to work with the modern Airport Utility.

To update Airport A1088, you need to use an old version of Apple Airport Utility (5.6.1), which can only run on very old operating systems.

see this link for reference.

Categories
Programming

Halfway to One Point Oh: UTM Version 0.5

Today I’ve finished version 0.5 of my new Gem, Universal Track Manager.

It’s a plug-and-play Rails engine that you install into your Ruby on Rails application with just three simple steps (see the README). You can then immediately pick up your visitors’:

IP address
Ad campaign where they came from
the browser they are using

In my next version, I’ll add support for http referrer and more too. Give it a try today.

If you like the Gem, please ‘star’ it on Github or download it from RubyGems (you do that just by running bundle install). Also, consider supporting it today with a small contribution today through the Github sponsors program. Sponsors levels start at just $1/month.

Categories
Programming

Universal Track Manager Version 0.4

Today I’m announcing Version 0.4 of my new Gem: Universal Track Manager.

It’s an great little utility project that will surely have appeal to many websites and developers.

Visitors come to your site every day. Along with their visits, four key pieces of information come along for the ride:

— IP address
— browser name (which lets you infer operating system and sometimes device)
— UTM parameters (if they clicked from another site or an ad campaign)
— HTTP referrer, (which shows if they clicked directly from another site to your site, even when no UTMs are set)

Universal Track Manager, a play-on-words that shares an acronym with “UTM Parameters,” is a plug & play gem to automatically scoop up this information and stash it into your database. You can think of it like a built-in Google Analytics (without the fancy dashboard).

With a tiny bit of trickery, support for Viewport size too is possible (width X height of the users’s window), which can let you determine if the user is on a desktop or mobile browser.

Today I’ve bumped the version up to 0.4. (I realize I made a 10x version change but this Gem is nearing its ‘version 1.0’ release so I am anticipating that when it is feature complete.)

This is the second version I’m dubbing as ‘public beta.’ Although this is production-quality code, it should be used with caution until it is no longer in BETA status. Please give it a try on your Rails projects today. With an easy 3-step installation into any Rails 4+ app and you can sit back and sweep up tracking info on your visitors.

*MOST* of the core functionality now works! This version 0.4 implements fully support for timestamping your visits, the user’s IP address, browser, and UTMs.

Support for HTTP referrer and more coming soon! Kindly submit feedback via Github.

Links:

Github Repo

Rubygems page