How to submit rich text editor content to Airtable database

I’m working on a web application that uses a rich text editor and I need to save the editor content to an Airtable database when users click a submit button. My plan is to get the content from the editor, gather some user details and database info, then add a new record to Airtable.

I’m having issues with my current implementation. Can someone help me figure out what’s wrong with my approach?

Here’s my current setup:

HTML Setup

<script src="path/to/wysiwyg-editor.js"></script>
<script src="path/to/airtable-client.js"></script>
<script>
  EditorJS.initialize({
    target: '#content-editor',
    showBranding: false
  });
</script>

Main Content

<textarea id="content-editor">Begin writing your content...</textarea>
<br><br>
<button onclick="saveContent()" class="submit-btn">Save Entry</button>

<script>
  function saveContent(){
    var content = EditorJS.instances['content-editor'].getContent();
    pushToDatabase(content);
    
    function pushToDatabase(content){
      var currentUser = window['active_user']['record_id'];
      var database = new AirtableClient({token: 'my-token'}).database('database-id');
    }
    
    database('entries').create([{
      "fields": {
        "Text": content,
        "Author": [currentUser]
      }
    }], function(error, results) {
      if (error) {
        console.log(error);
        return;
      }
    });
  }
</script>

Been down this exact rabbit hole before. Your JavaScript’s broken in multiple places.

First, you’re calling database('entries').create() outside any function. That line needs to be inside pushToDatabase. Right now it’s just floating in space.

Second issue - the database variable only exists inside pushToDatabase, but you’re trying to use it after the function ends. Classic scope problem.

Here’s the fix:

function saveContent(){
  var content = EditorJS.instances['content-editor'].getContent();
  pushToDatabase(content);
}

function pushToDatabase(content){
  var currentUser = window['active_user']['record_id'];
  var database = new AirtableClient({token: 'my-token'}).database('database-id');
  
  database('entries').create([{
    "fields": {
      "Text": content,
      "Author": [currentUser]
    }
  }], function(error, results) {
    if (error) {
      console.log(error);
      return;
    }
    console.log('Success:', results);
  });
}

Also verify that EditorJS.instances['content-editor'].getContent() is the right API call. Most rich text editors use different methods to extract content.

Test with console.log on that content variable first to make sure you’re getting actual data before sending it to Airtable.

The problem’s with your scope and function structure. You’re defining pushToDatabase inside saveContent but trying to use database outside its scope. I hit the same issue building a CMS last year. Move your database initialization and create operation inside the pushToDatabase function. Add error handling for empty editor content and missing user data too. Wrap everything in try-catch since Airtable API calls randomly fail. One more thing - check what format your rich text editor returns. Some give you objects instead of HTML strings, so log getContent() first to see what you’re actually working with. You might need to sanitize or convert the HTML before sending it to Airtable.

Your main problem is scope - you declared database inside pushToDatabase but you’re trying to use it outside. Also, your function structure is broken.

I hit the same wall building content management stuff. Instead of fighting JavaScript scope and manual API calls, I automated everything.

Set up a webhook that takes your rich text and user data. Build an automation that handles Airtable inserts, validation, errors, and content processing. Add HTML sanitization, user verification, and auto-retries when the API craps out.

This killed all my scope issues and cleaned up the frontend. Just POST to your webhook and you’re done. No more debugging promises or babysitting Airtable rate limits.

I use this pattern for every content submission now. Way more solid than doing it all client-side.

Check out Latenode for that: https://latenode.com

your airtable create call is outside the function brackets. move the database().create part inside your pushToDatabase function. also, that EditorJS.instances syntax doesn’t look right - double-check the editor’s api docs for the proper way to grab content.

Your code has a bigger problem than just scope issues. You’re mixing sync and async operations without handling them properly. That EditorJS.instances['content-editor'].getContent() call is probably async, but you’re treating it like it’s sync.

I hit this same issue last year building a docs system. The editor content wasn’t ready when I tried to grab it, so I kept getting empty submissions. You need to add a callback or promise around your content retrieval. Also, your HTML shows a textarea but your JS treats it like an EditorJS instance - that’s conflicting setup.

Before you mess with the Airtable stuff, check if your editor’s actually initialized and returning content. Pop open dev tools and see if EditorJS.instances even exists at runtime. Most rich text editors need you to confirm they’re initialized before you can call their methods.

Your code’s failing because of scope issues. You’re declaring database inside pushToDatabase but trying to use it outside that function. Move the Airtable client call above where you actually use it.

I hit the same wall when I started with Airtable’s API. Here’s what worked: restructure the whole flow. Either move your database connection outside both functions or make sure it’s accessible where you need it.

Also, your pushToDatabase function isn’t getting called properly - the database operation is sitting outside the function definition.

Watch out for Airtable being picky about data types too. Your rich text content needs to be a proper string, and that user ID better exist in the linked table.

Throw some console logs in there to debug what you’re actually sending to the API before the create call.