skip to Main Content

I have tried a lot of different ways to do this, with absolutely zero luck, over multiple days.

I am trying to use Solito Nativebase Universal Typescript repo to do this:

https://github.com/GeekyAnts/nativebase-templates/tree/master/solito-universal-app-template-nativebase-typescript

I have read, and tried everything on this page at least a dozen times:

https://github.com/GeekyAnts/nativebase-templates/issues/43

My current next.config.js file looks like this:

/** @type {import('next').NextConfig} */

const { withNativebase } = require('@native-base/next-adapter')
const withImages = require('next-images')
const { withExpo } = require('@expo/next-adapter')
const withFonts = require('next-fonts')

module.exports = withNativebase({
  dependencies: [
    '@expo/next-adapter',
    'next-images',
    'react-native-vector-icons',
    'react-native-vector-icons-for-web',
    'solito',
    'app',
  ],
  plugins: [
    [withFonts, { projectRoot: __dirname }],
    withImages,
    [withExpo, { projectRoot: __dirname }],
  ],
  nextConfig: {
    images: {
      disableStaticImages: true,
    },
    projectRoot: __dirname,
    reactStrictMode: true,
    webpack5: true,
    webpack: (config, options) => {
      config.resolve.alias = {
        ...(config.resolve.alias || {}),
        'react-native$': 'react-native-web',
        '@expo/vector-icons': 'react-native-vector-icons',
      }
      config.resolve.extensions = [
        '.web.js',
        '.web.ts',
        '.web.tsx',
        ...config.resolve.extensions,
      ]
      return config
    },
  },
})

I have also tried using @native-base/icons, again, no luck.

My end use case is this:

export const Cart = (props: IIconStyles) => {
  return (
    <Icon
      as={FontAwesome5}
      name="shopping-cart"
      size={props.size ? props.size : 6}
      color="gray.200"
    />
  )

Theoretically it SHOULD show a shopping cart, but instead, this is what I see:

question mark icon

So clearly there’s some font issue or other issue that is preventing it from loading in the actual SVG.

I can’t figure out what this is – I’ve tried rewriting my _document.tsx file like this:

https://docs.nativebase.io/nb-icons

I’ve tried adding this to my next.config.js:

 config.module.rules.push({
   test: /.ttf$/,
   loader: "url-loader", // or directly file-loader
   include: path.resolve(__dirname, "node_modules/@native-base/icons"),
 });

When I try to do something like this:

import fontsCSS from '@native-base/icons/FontsCSS';

in my _document.tsx file, I get the following error:

Module not found: Can't resolve '@native-base/icons/lib/FontsCSS'

Despite the fact that I’ve got @native-base/icons installed in my package.json, as well as having it in my Babel file per the instruction link above.

How do I get vector icons to work in Next?

Note, this is specifically Next/Expo/React Native

2

Answers


  1. You can read more about setup of next-adapter-icons here.

    I got it working with following approach,

    • next.config.js
    const { withNativebase } = require("@native-base/next-adapter");
    const path = require("path");
    
    module.exports = withNativebase({
      dependencies: ["@native-base/icons", "react-native-web-linear-gradient"],
      nextConfig: {
        webpack: (config, options) => {
          config.module.rules.push({
            test: /.ttf$/,
            loader: "url-loader", // or directly file-loader
            include: path.resolve(__dirname, "node_modules/@native-base/icons"),
          });
          config.resolve.alias = {
            ...(config.resolve.alias || {}),
            "react-native$": "react-native-web",
            "react-native-linear-gradient": "react-native-web-linear-gradient",
            "@expo/vector-icons": "react-native-vector-icons",
          };
          config.resolve.extensions = [
            ".web.js",
            ".web.ts",
            ".web.tsx",
            ...config.resolve.extensions,
          ];
          return config;
        },
      },
    });
    
    • pages/_document.js
    import React from 'react';
    import { DocumentContext, DocumentInitialProps } from 'next/document';
    import { default as NativebaseDocument } from '@native-base/next-adapter/document'
    
    // Icon Font Library Imports
    import MaterialIconsFont from '@native-base/icons/FontsCSS/MaterialIconsFontFaceCSS';
    import EntypoFontFaceCSS from '@native-base/icons/FontsCSS/EntypoFontFaceCSS';
    const fontsCSS = `${MaterialIconsFont} ${EntypoFontFaceCSS}`;
    
    export default class Document extends NativebaseDocument {
    
      static async getInitialProps(ctx) {
        const props = await super.getInitialProps(ctx);
        const styles = [
          <style key={'fontsCSS'} dangerouslySetInnerHTML={{ __html: fontsCSS }} />,
          ...props.styles,
        ]
        return { ...props, styles: React.Children.toArray(styles) }
      }
    }
    
    • pages/index.tsx
    import React from "react";
    import { Box, Icon } from "native-base";
    import Entypo from "@expo/vector-icons/Entypo";
    
    export default function App() {
      return (
        <Box>
          <Icon
            as={Entypo}
            name="user"
            color="coolGray.800"
            _dark={{
              color: "warmGray.50",
            }}
          />
        </Box>
      );
    }
    
    Login or Signup to reply.
  2. Using import like this:

    import MaterialIcons from '@expo/vector-icons/MaterialIcons'
    

    in place of:

    import { MaterialIcons } from '@expo/vector-icons'
    

    worked for me. I think this is because of the way babel/webpack handles imports in the template. I followed the steps here to setup the icons.

    Here’s what that looks like on web:
    screenshot

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search