Frequently Asked Questions

How do I debug my javascript or hosted web content? #

Please see Developing with Astro for a full description.

Why is the IDE saying that it cannot find grunt/node/npm? #

If you have already installed the prerequistites and Xcode/Android Studio is still unable to locate one of the tools, you may be required to setup a custom environment:

  1. Go into your /app directory and duplicate the file as

  2. Change file permissions by running the command: chmod +x

  3. Modify the path to point to the location where the tool is installed (you can use the command which <tool> to get the path).

Alternatively, you can run the command (replace <tool> with the missing tool):

cp app/ app/ && \
    sed -i '' '/export PATH="/d"' app/ && \
    echo "export PATH=\$PATH:\"$(which <tool> | sed 's/\/<tool>//')\"" >> app/ && \
    chmod +x app/

What is a Promise? #

A promise is a construct for writing asynchronous code in JavaScript and represents the eventual result of an asynchronous operation. To learn about how Astro uses promises, check out the Astro Overview.

For more information, check out these links:

Why does Astro use Promises? #

The Astro framework provides a common API for using native components on both Android and iOS. To communicate with the native platforms, Astro makes asynchronous calls between app.js and the native application hosting it; receiving responses to these asynchronous calls would require the use of callbacks, which can often result in Callback Hell. Promises are a great way to avoid deeply-nested callbacks, and they allow you to chain together other promises to write more imperative code, thus making them easier to work with.

How can I change the Navigation Plugin's behaviour when navigating to a new URL? #

As explained in more detail here, there are two typical setups for navigating with the Navigation Plugin:

  1. Stacking - Allow the Navigation Plugin to handle navigation by calling navigateToUrl. This automatically creates a new web view upon each navigation and pushes it onto the navigation stack.

  2. Non-stacking - Allow a WebView Plugin to handle navigation by creating a web view and calling navigateToPlugin to push it onto the navigation stack. This allows the web view to handle subsequent navigations (no stacking by default).

To override the default navigation behaviour in the first setup, you need to supply your own navigation handler function. Your handler should take a params argument that can be used to supply the parameters specified here.

For example:

// Define a custom navigation handler which takes in `params`
const customNavigationHandler = (params) => {
    if (!/^http(s)?:\/\/ {
        // Cancel navigations to
    } else {
            {navigationHandler: customNavigationHandler}

// Pass in the custom navigation handler to start overriding
// the default navigation behaviour
    {navigationHandler: customNavigationHandler}

To override the default navigation behaviour in the second setup, override the navigate event on the WebViewPlugin as described here.

How do I support orientation changes in an Astro app? #

Supporting different device orientations in an Astro app is accomplished with two steps:

  1. enable other orientations in the project
  2. implement orientation logic/styling

By default, Astro app projects are set to only support portrait orientation. The first step to supporting other orientations is configuring the native project to support them. Android and iOS accomplish this slightly differently.

Native Project Changes


In Android the supported orientations are controlled in the AndroidManifest.xml file. Open up the file and find the MainActivity entry. It will look something like this:


Update the android:screenOrientation value as needed. The full list of valid values can be found here.


In iOS the supported orientations are controlled in the project settings. Open up the workspace in Xcode and select the app project in the Project navigator. Select the General tab. Under the Deployment Info section check the orientations that you would like your app to support.

App.js (Worker) and Web changes

Once you have configured the native project to support other orientations, you are ready to continue with orientation support. There are two basic methods of supporting different orientations:

  1. Execute code on rotation To be notified when the device orientation changes, you can use the resize event in the worker (aka. app.js), or any web view, and execute whatever code is necessary at that time. For example:

     const handleOrientationChanged = () => {
          const isLandscape = (window.innerWidth > window.innerHeight)
          if (isLandscape) {
              // do something for landscape orientations
          } else {
              // do something for portrait orientations
     window.addEventListener('resize', handleOrientationChanged)
  2. Use CSS to style the supported orientations differently Using CSS you can use media queries to style your web content differently depending on if the device is in a portrait or landscape orientation as follows:

     @media (orientation: portrait) {
         // ... portrait styles
     @media (orientation: landscape) {
         // ... landscape styles

    Once you have these styles set up the layout will automatically adjust as the device is rotated. You can use this approach in any web content that is loaded within a WebViewPlugin in an Astro app.

Why doesn't Astro.trigger() or Astro.jsRpcMethod() work on my site?

This might be caused by an incorrectly configured Content-Security-Policy (CSP) header sent from the server. Check out the Supported Platforms documentation for more information.

You can verify if CSP is an issue by attaching Safari (or Chrome if you're working on Android) to the page that contains problematic page. Now invoke the action that uses the Astro client (trigger() or jsRpcMethod()). If CSP is blocking communication, you'll see a message like the following in the Console section of the web developer tools:

Refused to load astro://astro-check-queue because it appears in neither the child-src directive nor the default-src directive of the Content Security Policy.