react-native-svg-transformer: With Expo web: Failed to execute 'createElement' on 'Document'

Hello,

I am using Expo 39’s managed workflow.

I followed the installation instruction, created the metro.config.js file, and copy-pasted the content from the instructions. I also added the packagerOpts field to my app.json.

For testing purpose, I renamed my SVG file to logo.svg and used the following code in my app:

import Logo from "../../assets/images/avatars/logo.svg"

function TestComp() {
	const size = 120;
	return <Logo width={size} height={size}/>
}

Unfortunately, I am now getting the error: InvalidCharacterError: Failed to execute 'createElement' on 'Document': The tag name provided ('/static/media/logo.6a5b59b1.svg') is not a valid name.

Any idea about what is causing the error?

I don’t know if it is related, but I do have a babel.config.js file in my root folder.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 3
  • Comments: 15 (2 by maintainers)

Most upvoted comments

encountered the same issue,

i solve this by adding babel-plugin-inline-react-svg as dev dependencies

then add this to your babel.config.js

{ "plugins": [ "inline-react-svg" ] }

thanks to this guy https://github.com/boopathi/react-svg-loader/issues/197#issuecomment-377562447

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android.

O erro: Invariant Violation: View config getter callback for component caminho must be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look:

https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

@divonelnc I just merged a PR to update the instructions for Expo, can you check the README again if that matches the config that you have in use?

I am getting the same issue with SDK 40 with an expo managed app:

Error

Unhandled Rejection (InvalidCharacterError): Failed to execute 'createElement' on 'Document': The tag name provided ('/static/media/swiped-all.eb95b811.svg') is not a valid name

Steps taken

I have placed my SVGs under ./src/assets/.... An example import I’m doing is:

import SwipedAll from "../assets/swiped-all.svg";

Notably, if I use babel-plugin-inline-react-svg as a plugin, it works like a charm on web: however it is not compatible with mobile.

Config files

# ./metro.config.js
const { getDefaultConfig } = require("@expo/metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig(__dirname);
  console.log(sourceExts);
  console.log(assetExts);
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer"),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"],
    },
  };
})();
# app.json
{
  "expo": {
    "scheme": "topspin",  
    "name": "topspin",
    "slug": "topspin",
    "platforms": [
      "ios",
      "android"
    ],
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./src/assets/icon.png",
    "splash": {
      "image": "./src/assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.topspin.topspin",
      "googleServicesFile": "./GoogleService-Info.plist"
    },
    "android": {
      "package": "com.topspin.topspin",
      "googleServicesFile": "./google-services.json",
      "useNextNotificationsApi": true
    },
    "web": {
      "favicon": "./src/assets/favicon.png",
      "build": {
        "babel": {
          "include": ["react-router-native"]
        }
      }
    }
  }
}
# ./babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo", "@babel/preset-typescript"],
  };
};
# package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "test": "jest --config jest.config.js"
  },
  "dependencies": {
    "@apollo/client": "^3.2.5",
    "@expo-google-fonts/inter": "^0.1.0",
    "@ptomasroos/react-native-multi-slider": "^2.2.2",
    "@react-native-community/masked-view": "0.1.10",
    "@types/jest": "^26.0.19",
    "@types/react-router-native": "^5.1.0",
    "cloudinary-core": "^2.11.3",
    "expo": "^40.0.0",
    "expo-app-loading": "^1.0.1",
    "expo-auth-session": "~3.0.0",
    "expo-cli": "^4.0.17",
    "expo-constants": "~9.3.3",
    "expo-facebook": "~9.1.0",
    "expo-file-system": "~9.3.0",
    "expo-font": "~8.4.0",
    "expo-image-picker": "~9.2.0",
    "expo-notifications": "~0.8.2",
    "expo-random": "~10.0.0",
    "expo-status-bar": "~1.0.3",
    "firebase": "7.9.0",
    "graphql": "^15.4.0",
    "native-base": "^2.13.14",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-hook-form": "^6.11.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-deck-swiper": "^2.0.5",
    "react-native-elements": "^3.0.0-alpha.1",
    "react-native-expo-viewport-units": "^0.0.8",
    "react-native-fbsdk": "^2.0.0",
    "react-native-gesture-handler": "~1.8.0",
    "react-native-reanimated": "~1.13.0",
    "react-native-safe-area-context": "3.1.9",
    "react-native-screens": "~2.15.0",
    "react-native-svg": "12.1.0",
    "react-native-web": "~0.13.12",
    "react-router-native": "^5.2.0"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "@babel/preset-env": "^7.12.11",
    "@babel/preset-typescript": "^7.12.7",
    "@expo/webpack-config": "~0.12.45",
    "@testing-library/jest-dom": "^5.11.5",
    "@testing-library/react-native": "^7.1.0",
    "@types/react": "~16.9.35",
    "@types/react-dom": "~16.9.8",
    "@types/react-native": "~0.63.2",
    "@types/react-test-renderer": "^17.0.0",
    "babel-jest": "^26.6.3",
    "babel-plugin-inline-react-svg": "^1.1.2",
    "eslint": "^7.13.0",
    "eslint-plugin-jest": "^24.1.3",
    "jest-expo": "^40.0.0",
    "node-fetch": "^2.6.1",
    "react-native-svg-transformer": "^0.14.3",
    "react-test-renderer": "^17.0.1",
    "ts-loader": "^8.0.13",
    "typescript": "~4.0.0"
  },
  "private": true
}

# ./webpack.config.js
const createExpoWebpackConfigAsync = require("@expo/webpack-config");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(
    {
      ...env,
      babel: {
        dangerouslyAddModulePathsToTranspile: [
          "@ptomasroos/react-native-multi-slider",
        ],
      },
    },
    argv
  );
  return config;
};

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android. O erro: Invariant Violation: View config getter callback for component caminho must be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look: https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

I saw that you removed the repository with the temp fix and just wondering if you’ve found a better, permanent solution for this, maybe?

Yes, the author suggested a solution to me that solved the problem for me, you can remove the workaround and implement it:

https://github.com/kristerkari/react-native-svg-transformer/issues/135#issuecomment-1008310514

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android. O erro: Invariant Violation: View config getter callback for component caminho must be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look:

https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

I saw that you removed the repository with the temp fix and just wondering if you’ve found a better, permanent solution for this, maybe?

SVG import in create-react-app should be like this:

import { ReactComponent as Logo } from "../../assets/images/avatars/logo.svg"

In native it should be like this:

import Logo from "../../assets/images/avatars/logo.svg"

The import syntax for create-react-app is different from the syntax for native. @kristerkari any way we can fix this ?