Dynatrace meets managed Expo app

Jeanette Popken
Adventures in Expo
Published in
3 min readFeb 7, 2023

Want to use Dynatrace in your managed Expo app but scared you will have to eject or write a custom config plugin? Not today!

Adventures in Expo tackles Dynatrace

This magic sauce does require using development builds. Development builds in Expo allow you to use 3rd party libraries that change native code (or you can change it yourself) without having to eject your app.

Check out Expo’s guide: Getting Started guide for development builds

Once you are up and running with development builds, you are ready to bring in Dynatrace.

You first need to do the setup on Dynatrace’s side and create a mobile app in Dynatrace. You can follow those steps here.

Now the fun can really begin.

Use the local expo-cli to install the correct (if known) version:

npx expo install @dynatrace/react-native-plugin

Follow the plugin’s documentation to configure the generic generated dynatrace.config.js file with the correct information.

Customize the metro bundler by creating or updating the project’s root metro.config.js

const { getDefaultConfig } = require('@expo/metro-config');
const config = getDefaultConfig(__dirname);

config.transformer.babelTransformerPath = require.resolve('@dynatrace/react-native-plugin/lib/dynatrace-transformer');
config.reporter = require("@dynatrace/react-native-plugin/lib/dynatrace-reporter");

module.exports = config;

Now here is the tricky party. We need to update our babel.config.js but Dynatrace’s documentation splits here with two different directions.

For Metro 0.72.0 and above then use:

module.exports = {
presets: [
['module:metro-react-native-babel-preset'],
],
plugins: [
[
'@babel/plugin-transform-react-jsx',
{
runtime: 'automatic',
importSource: "@dynatrace/react-native-plugin/lib"
},
],
],
};

And for Expo 44 and above or babel-preset-expo 9.0.0 and above then use:

module.exports = {
presets: [
['babel-preset-expo',
{
jsxRuntime: 'automatic',
jsxImportSource: '@dynatrace/react-native-plugin/lib',
},
],
],
};

But what if you fit both cases? For instance, you are using a managed Expo app that is above SDK 44 and uses babel-preset-expo 9.0.0 and above but already has babel.config.js that is transforming your source code via the module:metro-react-native-babel-preset preset?

I’ll save you some trouble, following either of their documented options separately won’t work for you.

And deep breath, you don’t need to write a custom config plugin.

We just need to combine everything together. So your babel.config.js would use both presets and you don’t need to add anything in the plugins at all.

presets: [
['babel-preset-expo',
{
jsxRuntime: 'automatic',
jsxImportSource: '@dynatrace/react-native-plugin/lib',
},
],
['module:metro-react-native-babel-preset']
],

Bam! Presto. Your source code is ready to be transformed by all the right pieces you have in your project.

Now for the last trick.

We need to run the instrumentation script but when the native directories are generated. Don’t worry though, with EAS builds, there are a few build hooks exposed. One of them being the ‘eas-build-post-install’ which is happens to get called after yarn install, (for ios also after pod install) and npx expo prebuild. And the prebuild command creates the native directories. So we will manually call the instrumentation script from dynatrace after this step to ensure our app is correctly instrumented.

"eas-build-post-install": "npx instrumentDynatrace plist='./ios/YourProjectName/Info.plist'"

Kick off a new development build (so the native code can be re-compiled), install it on your device and start your project (and it would be a good idea to clear your metro cache.)

npx expo start --clear

Then you can see the session in your application in Dynatrace. So all that is left is customize the user tags and actions and to what extent you want to capture data and errors. Check this out for more info. Happy mobile app monitoring!

--

--