> For the complete documentation index, see [llms.txt](https://docs.buildnatively.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.buildnatively.com/guides/integration/audio-recorder.md).

# Audio Recorder

## What is Audio Recorder?

The Audio Recorder feature gives your app access to the device's native audio recording interface, letting users record audio without leaving the app. The recording is returned as a Base64-encoded string, which you can play back or upload to your server.

Audio Recorder requests [microphone](/natively-platform/features/microphone.md) permission on both iOS and Android. Users will be prompted to grant this permission the first time the feature is used.

## Prerequisites

{% hint style="success" %}
This feature is available in all plans. [See all plans](/getting-started/subscription-plans.md)
{% endhint %}

{% hint style="info" %}
Audio Recorder uses the [Microphone](/natively-platform/features/microphone.md) feature, which is enabled by default for all new apps. If the Microphone has been disabled for your app, you'll need to re-enable it for Audio Recorder to work.
{% endhint %}

## Implementation

Choose your integration method below: **Bubble.io Plugin** (No-Code), **JavaScript SDK** (Code), or **AI Agents** (for AI-powered editors like Lovable, Base44, and Replit).

### Initialization

{% tabs %}
{% tab title="Bubble.io Plugin" %}
**Check Plugin**

Before starting, verify if the Natively plugin is already installed in your Bubble project.

1. Open your Bubble editor and navigate to the Plugins tab in the left sidebar.
2. **Check Installed Plugins:** Look through your list of installed plugins for "Natively iOS & Android app builder".
   * If it IS installed: Check the version number. If an update is available (e.g., you see a button saying "Update"), click it to ensure you have the latest features and bug fixes.

<figure><img src="https://docs.buildnatively.com/~gitbook/image?url=https%3A%2F%2F3352617162-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F90tV7pYflEQdiAr2VfWu%252Fuploads%252FmfnSUug82IdnxOAoBrak%252Fnatively_app_builder_bubble_plugin_update.png%3Falt%3Dmedia%26token%3Dc193f69f-b03b-4be4-b80b-f34ba37ac212&#x26;width=768&#x26;dpr=3&#x26;quality=100&#x26;sign=a89e4510&#x26;sv=2" alt=""><figcaption></figcaption></figure>

* If it is NOT installed: Click the + Add plugins button, search for "Natively", and click Install.

<figure><img src="https://docs.buildnatively.com/~gitbook/image?url=https%3A%2F%2F3352617162-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F90tV7pYflEQdiAr2VfWu%252Fuploads%252FC5rA42yQHcN1uGKFbzmF%252Fnatively_app_builder_bubble_plugin.png%3Falt%3Dmedia%26token%3Dd9706d9b-dbe8-459b-b9b3-5667648aa4b7&#x26;width=768&#x26;dpr=3&#x26;quality=100&#x26;sign=9aae2297&#x26;sv=2" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="JavaScript SDK" %}
**Check SDK**

Before writing any logic, ensure the Natively SDK is correctly installed and up-to-date in your codebase.

1. Open your project's main HTML file (or header settings) and look for the Natively script tag inside the `<head>` section.
2. Install/Update: If missing or outdated, add the following code. You can specify the SDK version in the URL (e.g., `@2.26.0`).

```javascript
<head>
  <script async onload="nativelyOnLoad()" src="https://cdn.jsdelivr.net/npm/natively@2.26.0/natively-frontend.min.js"></script>
</head>
```

{% hint style="info" %}
To ensure you are using the most up-to-date version, check the [Natively GitHub releases page](https://github.com/buildnatively/js-sdk/releases) for the latest version number.
{% endhint %}
{% endtab %}

{% tab title="AI Agents" %}
**Initialize the SDK**

AI-powered editors like Lovable, Base44, and Replit use the JavaScript SDK to implement Natively features. Before implementing any feature, the Natively SDK must be initialized in your project.

Copy the line below and paste it into your AI agent to check and set up the Natively SDK in your project.

```
Check if the following Natively SDK script is present in the <head> of index.html. If missing or outdated, add it: <script async onload="nativelyOnLoad()" src="https://cdn.jsdelivr.net/npm/natively@2.26.0/natively-frontend.min.js"></script><script>function nativelyOnLoad() { window.natively.setDebug(true); console.log("✅ Natively SDK loaded successfully."); }</script> For reference: https://docs.buildnatively.com/guides/integration/how-to-get-started https://github.com/buildnatively/js-sdk/releases
```

{% endtab %}
{% endtabs %}

### Setup Logic

{% tabs %}
{% tab title="Bubble.io Plugin" %}

### \[Element] Natively - Audio Recorder&#x20;

#### Events:

* **Recorder Result Updated** - called after the recording finishes.
* **Recorder Cancelled** - called when the user closes the recorder without recording.
* **File Uploaded** - called after the file is successfully uploaded to S3 (the file URL is available in the element's state).
* **File Size over limit** - triggered when the recorded file exceeds the **File Size Limit** parameter.

#### States:

* **Recorder Result (Base64)** - Base64 string representation of the recorded audio, for custom uploading.
* **Recorder Result (Content Type)** - `audio/m4a` (iOS) or `audio/wav` (Android).
* **Uploaded File URL** - Amazon S3 file URL (only populated if upload is enabled).
* **File Size** - size of the latest recording result, in KB.

#### Actions:

* **Show Recorder**
  * **Upload File** - checkbox; uploads the recording to Amazon S3.
  * **File Name** - used if **Upload File** is checked.
  * **File Size Limit** - in KB; prevents uploading files larger than this limit to Bubble's Amazon S3.
  * **Max Duration** - maximum recording duration in seconds. Leave at 0 for unlimited duration.
    {% endtab %}

{% tab title="JavaScript SDK" %}

```javascript
// ============================================================================
// NATIVELY AUDIO RECORDER - DOCUMENTATION & EXAMPLES
// ============================================================================

const audioRecorder = new NativelyAudioRecorder();

// ============================================================================
// ALL AVAILABLE METHODS
// ============================================================================
// audioRecorder.showRecorder(max_duration, callback)
//   - Opens the native audio recorder UI and returns the result once the user finishes or cancels.
//   - max_duration: number — maximum recording duration in seconds. Pass 0 (or omit) for unlimited duration.
//   - resp.base64: string — Base64-encoded recording
//   - resp.content_type: string — "audio/m4a" (iOS) or "audio/wav" (Android)
//   - resp.size: number — file size in KB
//   - resp.status: string — "SUCCESS" or "CANCELLED"

// --- Audio Recorder. Show Recorder Example. Start ---

const max_duration = 0; // 0 = unlimited duration

const audio_recorder_callback = function (resp) {
  if (resp.status === "CANCELLED") {
    console.log("User closed the recorder without recording.");
    return;
  }

  console.log(resp.base64);        // Base64-encoded recording
  console.log(resp.content_type);  // "audio/m4a" for iOS or "audio/wav" for Android
  console.log(resp.size);          // file size in KB
};

audioRecorder.showRecorder(max_duration, audio_recorder_callback);

// --- Audio Recorder. Show Recorder Example. End ---
```

{% endtab %}

{% tab title="AI Agents" %}
AI-powered editors like Lovable, Base44, and Replit use the JavaScript SDK to implement Natively features.&#x20;

Copy the line below and paste it into your AI agent.&#x20;

<pre><code>[<a data-footnote-ref href="#user-content-fn-1">Your feature description</a>] using the Natively Audio Recorder SDK: const audioRecorder = new NativelyAudioRecorder(); audioRecorder.showRecorder(max_duration, callback) opens the native recorder UI. max_duration: number — maximum recording duration in seconds, pass 0 for unlimited. Returns resp.base64 (Base64-encoded recording), resp.content_type ("audio/m4a" for iOS or "audio/wav" for Android), resp.size (file size in KB), and resp.status ("SUCCESS" or "CANCELLED" if the user closed the recorder without recording). For reference: https://docs.buildnatively.com/guides/integration/audio-recorder
</code></pre>

{% hint style="warning" %}
Replace the placeholder at the beginning with a description of what you want to build - for example: "Add a voice-memo recorder to my journal app, limited to 60 seconds, that uploads the recording to my backend".
{% endhint %}
{% endtab %}
{% endtabs %}

### How to use

#### Check `resp.status` before processing the recording

A cancelled recording still triggers the callback - always confirm `resp.status === "SUCCESS"` before uploading or storing `resp.base64`.

#### Set a `max_duration` for predictable file sizes

Long recordings produce large Base64 payloads. Cap recording length if your backend has upload size limits - for example, 60 seconds for a voice memo, or a few minutes for a longer note.

#### Convert content type before playback if needed

iOS returns `audio/m4a` and Android returns `audio/wav`. If you play recordings back across platforms, confirm your player or backend handles both formats.

## Troubleshooting

<details>

<summary>Audio Recorder doesn't do anything in a web browser</summary>

This is a native feature and won't function in Safari, Chrome, or any browser preview - test it in a real build installed on a device.

</details>

<details>

<summary>Recording fails, or the user is never prompted for microphone access</summary>

Check whether the [Microphone](/natively-platform/features/microphone.md) feature is enabled in the Natively Dashboard. If the user previously denied microphone access, direct them to [Open App Settings](/guides/integration/open-app-settings.md) to re-enable it.

</details>

[^1]: Replace this placeholder
