---
updatedAt: 2025-06-16T21:15:14.000Z
---

Fetch the complete documentation index at: https://docs.ultralig.ht/llms.txt. Use this file to discover all available pages before exploring further.

# Evaluating a String of JS

## Using View::EvaluateScript()

The easiest way to evaluate a string of JavaScript in C++ is by using [`View::EvaluateScript()`](https://ultralig.ht/api/cpp/1_4_0/classultralight_1_1_view.html#afbe74f175bdae8f0c128b059eead7198)

```cplusplus
///
/// Use LoadListener::OnDOMReady to wait for the DOM to load.
///
void MyApp::OnDOMReady(View* caller,
                       uint64_t frame_id,
                       bool is_main_frame,
                       const String& url) {
  ///
  /// Execute a string of JavaScript
  ///
  view->EvaluateScript("document.body.innerHTML = 'Ultralight rocks!';");
}
```

## Handling Results

[`View::EvaluateScript()`](https://ultralig.ht/api/cpp/1_4_0/classultralight_1_1_view.html#afbe74f175bdae8f0c128b059eead7198) can return the result from a script execution, if any.

The result is returned as a String.

```cplusplus
///
/// Use LoadListener::OnDOMReady to wait for the DOM to load.
///
void MyApp::OnDOMReady(View* caller,
                       uint64_t frame_id,
                       bool is_main_frame,
                       const String& url) {
  
  ///
  /// Evaluate a string of JavaScript, store result in 'result'
  ///
  String result = view->EvaluateScript("1 + 1");
  
  ///
  /// result should now contain "2"
  ///
  
}
```

## Using JSEvaluateScript() Directly

[`View::EvaluateScript()`](https://ultralig.ht/api/cpp/1_4_0/classultralight_1_1_view.html#afbe74f175bdae8f0c128b059eead7198) is really just a wrapper for JavaScriptCore's [`JSEvaluateScript()`](https://ultralig.ht/api/cpp/1_4_0/_j_s_base_8h.html#a8cb4610a07b0bb0717f1225f9d5b8585). This API function offers lower-level control over script execution (exception handling, overriding `this` object, etc.).

To use this API function we're going to need to create a JavaScript string with [`JSStringCreateWithUTF8CString()`](https://ultralig.ht/api/cpp/1_4_0/_j_s_string_ref_8h.html#a7e105133c4662e75741fec26aa47e006) and then pass it to [`JSEvaluateScript()`](https://ultralig.ht/api/cpp/1_4_0/_j_s_base_8h.html#a8cb4610a07b0bb0717f1225f9d5b8585).

```cplusplus
///
/// Use LoadListener::OnDOMReady to wait for the DOM to load.
///
void MyApp::OnDOMReady(View* caller,
                       uint64_t frame_id,
                       bool is_main_frame,
                       const String& url) {
  ///
  /// Acquire the JS execution context for the current page.
  ///
  auto scoped_context = caller->LockJSContext();
  
  ///
  /// Typecast to the underlying JSContextRef.
  ///
  JSContextRef ctx = (*scoped_context);
  
  const char* script = "document.body.innerHTML = 'Ultralight rocks!';";
  
  ///
  /// Create our string of JavaScript
  ///
  JSStringRef str = JSStringCreateWithUTF8CString(script);
  
  ///
  /// Execute it with JSEvaluateScript, ignoring other parameters for now
  ///
  JSEvaluateScript(ctx, str, 0, 0, 0, 0);
  
  ///
  /// Release our string (we only Release what we Create)
  ///
  JSStringRelease(str);
  
}
```

## Managing string lifetime with Retain / Release

The API follows a simple rule-- anything you **"Create"** you must **"Release"**.

For example, in the above code snippet we called [`JSStringCreateWithUTF8CString`](https://ultralig.ht/api/cpp/1_4_0/_j_s_string_ref_8h.html#a7e105133c4662e75741fec26aa47e006). This API function has the word `Create` in it so we must release the created object with [`JSStringRelease()`](https://ultralig.ht/api/cpp/1_4_0/_j_s_string_ref_8h.html#a446d045a7d4680b37a31fb09ffed86c3) to avoid a memory leak.

If you want to increase the ref-count (to retain the object in a C++ wrapper, for instance), you can call [`JSStringRetain()`](https://ultralig.ht/api/cpp/1_4_0/_j_s_string_ref_8h.html#ae415d110389cc5f7d89beff61fbf7499).

The API provides a [`JSRetainPtr<>`](https://ultralig.ht/api/cpp/1_4_0/_j_s_retain_ptr_8h.html) for C++ that automatically manages lifetime for you. Just call `adopt()` with any of the `JSStringCreate` methods to create a managed string object.

```cplusplus
#include <JavaScriptCore/JSRetainPtr.h>

///
/// Use LoadListener::OnDOMReady to wait for the DOM to load.
///
void MyApp::OnDOMReady(View* caller,
                       uint64_t frame_id,
                       bool is_main_frame,
                       const String& url) {
  ///
  /// Acquire the JS execution context for the current page.
  ///
  auto scoped_context = caller->LockJSContext();
  
  ///
  /// Typecast to the underlying JSContextRef.
  ///
  JSContextRef ctx = (*scoped_context);
  
  const char* script = "document.body.innerHTML = 'Ultralight rocks!';";
  
  ///
  /// Create our string of JavaScript, automatically managed by JSRetainPtr
  ///
  JSRetainPtr<JSStringRef> str = adopt(
    JSStringCreateWithUTF8CString(script));
  
  ///
  /// Execute it with JSEvaluateScript, ignoring other parameters for now
  ///
  JSEvaluateScript(ctx, str.get(), 0, 0, 0, 0);
  
}
```