Lessons from CodeSandbox: Send User Feedback to Airtable using React

A series about taking code apart.

CodeSandbox is awesome.

It’s an entire IDE (integrated development environment) for web apps that runs inside your browser.

The best thing about it though, is that it’s open source. And the best thing about open source projects is that we can learn from their source code.

In this series I’ll be tearing down the code that makes CodeSandbox great in order to find some tips that you can use on your own projects. Kind of like ifixit, but for JavaScript.

  • Part 1: Send user feedback to Airtable using React
  • Part 2: Honour your users Do Not Track browser settings in React (coming soon)
  • Part 3: Use Cerebral and MobX to manage complex application logic in React (coming soon)
  • Part 4: Use “template classes” to group data and functionality together (coming soon)

Tear it down!

We’ll be looking at the codesandbox-client repository (Github link here if you want to follow along in your own code editor). On first impressions, it’s a quite large JavaScript repository. lerna is used to split the codebase into manageable smaller sections.

For this teardown series, we’re going to look at the app package (located in the packages/app folder). The app package contains the full CodeSandbox app as well as the embedded app you might have seen on Medium or other websites. It’s written in React 16.5.2.

The repository commit hash at the time of writing is 450afd6.

We ❤️ user feedback

Good user feedback is important because it helps us developers prioritise the next feature to build or bug to fix. Getting feedback could be as simple as sitting with users while they use your app, but building feedback submission channels into your app means you’ll get a stream of bug reports and feature requests without spending time interviewing people.

Airtable is really good for collecting feedback.

If you haven’t used it before, it’s kind of like Microsoft Excel or Google Sheets, but on steroids. It feels a little bit less like a spreadsheet app and more like a proper database.

It’s good for feedback because it’s built for less technical-minded people. Your product manager or UI designer can easily access the data, as opposed to something like, say, sending feedback to MongoDB, where you might need to help them out.

This is how CodeSandbox collects feedback from users:

Above: me sharing how much I love CodeSandbox ❤️

Once you hit submit, a new entry in CodeSandbox’s Airtable is generated with your feedback as well as some relevant user information. In the next section, I’ll run through how it’s built, and how you can use it in your own apps.

Sending feedback to Airtable

There are three separate files responsible for Airtable functionality.

setAirtable.js sets up the Airtable JavaScript API with a specified API key. This is nice because it encapsulates the API key in a single place within the repository.

// packages/app/src/app/store/utils/setAirtable.js
import Airtable from 'airtable';
export default new Airtable({ apiKey: '<YOUR_AIRTABLE_API_KEY>' });

pushToAirtable.js connects to the Airtable base (their term for a particular spreadsheet), and wraps the Airtable ‘create record’ function with application-specific arguments relating to our feedback. It also handles errors, logging them to the console. Note that the function returns a Promise, which was chosen so that the function could possibly be called in a promise chain.

// packages/app/src/app/store/utils/pushToAirtable.js
import Airtable from './setAirtable';
const base = Airtable.base('<YOUR_AIRTABLE_BASE_KEY>');
export default ({ feedback, emoji, sandboxId, username, email }) =>
  new Promise((resolve, reject) => {
      err => {
        if (err) {

Feedback.js is the React feedback modal component which calls pushToAirtable(). I also like the way that props and user are destructured inside sendFeedback().

// packages/app/src/app/pages/common/Modals/FeedbackModal/Feedback.js
// Some code has been omitted for brevity
import pushToAirtable from 'app/store/utils/pushToAirtable';
function sendFeedback(props) {
  const { feedback, emoji, sandboxId, user } = props;
  const { username, email } = user || {};
  return pushToAirtable({ feedback, emoji, sandboxId, username, email });
class Feedback extends React.Component {
  onSubmit = evt => {
    const { id, user, signals } = this.props;
    const { feedback, emoji } = this.state;
    this.setState({ loading: true }, () => {
        sandboxId: id,
  render() {
    return (
      <form onSubmit={this.onSubmit}>

So really, there’s not that much to it. It’s as simple as:

  1. Create a file which encapsulates your Airtable API key (setAirtable.js)
  2. Create wrapper functions for any Airtable functions, making the arguments application specific (pushToAirtable.js)
  3. Call the function inside onSubmit() for forms or onClick() for buttons inside your React component (Feedback.js)

And why stop at collecting just user feedback with Airtable? You could expand on this method to send other kinds of data too, such as particular application events or logs. I’d love to hear about how you use it in your own projects.

So we’ve got the feedback. But what next?

The one thing that we can’t read from the source code is how the user feedback is dealt with once it’s received in the Airtable base. Ives van Hoorne, the creator of CodeSandbox, was kind enough to share some more about their Airtable setup with me:

Thats all for this teardown!

In the next article, we’ll take a tip from CodeSandbox in handling Do Not Track settings from your users.

Follow me on Twitter — I’ll be posting future articles there as I write them.

Have you read through the CodeSandbox source code yourself? If you learnt anything interesting from it, please let me know in the comments 🙌

Lessons from CodeSandbox: Send User Feedback to Airtable using React was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Reply

Your email address will not be published. Required fields are marked *