Experiencing difficulties loading Expo Vector Icons in Nextjs

I've spent countless hours trying various methods to accomplish this task, but unfortunately, I have had no luck so far.

My goal is to utilize the Solito Nativebase Universal Typescript repository for this purpose:

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

I have exhaustively explored and attempted everything outlined on this page multiple times:

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

The contents of my current next.config.js file are as follows:

/** @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 made attempts using @native-base/icons, but without success.

This is intended to produce the following outcome:

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

In theory, it should display a shopping cart icon, however, instead, what I am seeing is depicted in this image:

https://i.stack.imgur.com/I9JMq.png

Evidently, there seems to be an issue related to fonts or some other factor hindering the loading of the SVG.

I am struggling to identify the root cause - I have tried modifying my _document.tsx file according to the guidelines provided here:

I have also included this snippet in 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 attempting something like this:

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

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

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

Even though I have @native-base/icons installed in my package.json and referenced in my Babel configuration per the instructions mentioned above.

How can I successfully integrate vector icons in Next.js?

Note that this pertains specifically to Next.js/Expo/React Native development.

Answer №1

To learn more about setting up next-adapter-icons, visit this link.

Here is the method I used to make it work:

  • 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",
        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>
  );
}

Answer №2

By simply using the import statement like this:

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

instead of:

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

I found success. It seems that the way babel/webpack handles imports in the template played a role in this solution. I referenced the steps provided here to configure the icons.

This is how it appears on the web: https://i.stack.imgur.com/f9bV2.png

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to insert user data into a hidden input field

I am facing an issue with the input field on my website. Users can enter their desired input, and this data is copied into a hidden input field. However, the problem arises when new data replaces the old data. This is where I copy all the data: $('# ...

Retrieving JSON data value without a key using AngularJS

I am struggling to retrieve a data value from a JSON array in Angular that does not have a key value. While I have come across examples of extracting values with keys, I haven't been able to crack this particular piece. The JSON returned from the API ...

Issue with hook not updating when invoked inside useEffect

I'm encountering an issue with updating the state after fetching data from my API. The API response seems to be correct, but for some reason, my weatherData-hook is not getting updated and it returns undefined. Can anyone point out what mistake I migh ...

Issue with Angular.forEach loop malfunctioning

Here is the code for my custom filter that includes a parameter called viewbookoption, which is a dropdown value. Depending on the selected value from the dropdown, the data will be displayed in a grid. I have used a forEach loop in this filter, but it see ...

The JSON object, which has been converted into a string and sent over the network,

Attempting to set up a websocket server using TypeScript in Node.js, the following code was used: ws.on('message', (msg: string) => { console.log("got message:" + msg); const m = JSON.parse(msg); console.log(m); ...

Incorporating multiple web services into a React JS project to populate a Material UI dropdown efficiently

I have some code that is calling a web service and I have a few questions. Firstly, what is the best way to call a second web service? Currently, I am calling one and displaying the data in a list. But if I need to call a second web service, should I also ...

Tips for simulating focus on a Material-ui TextField with a button press

My web application features a unique method for indirectly filling in text fields. Since there are multiple clicks involved (specifically in a calendar context) and numerous fields to fill, I want to provide users with a visual indication of which field th ...

Is it appropriate to use a component inside an entry component?

I'm currently working on a component that triggers a function to open a window: @Component({ selector: 'app-deposits', templateUrl: './deposits.component.html', styleUrls: ['./deposits.component.scss&apo ...

The built-in functions of Wordpress are not able to be identified in the ajax PHP file

As a newcomer to Wordpress development, I am facing challenges with implementing ajax on my WordPress site. I am currently working on a plugin that requires the use of ajax. However, my php file (xxxecommerce.ajax.php) is not recognizing the built-in Word ...

Multiplying array elements within the Vuex state with the assistance of Socket.io

I have developed an application using Vue and Vuex that connects to a Node/Express backend with Socket.IO to instantly push data from the server to the client when necessary. The data sent to the clients is in the form of objects, which are then stored in ...

How come my counter is still at 0 even though I incremented it within the loop?

Within my HTML file, the code snippet below is present: <div id="userCount" class="number count-to" data-from="0" data-to="" data-speed="1000" data-fresh-interval="20"></div> In my Ja ...

Displaying JSON data from the API on a webpage within a NodeJS weather application

Currently, I am in the process of developing a weather application using NodeJS. I have successfully retrieved JSON formatted data from the weather site's API. Nonetheless, I am perplexed about how to transmit this data to the application. Below is a ...

Tips for displaying personalized data with MUI DatePicker

I need to create a React TypeScript component that displays a MUI DatePicker. When a new date is selected, I want a custom component (called <Badge>) to appear in the value field. Previously, I was able to achieve this with MUI Select: return ( ...

jQuery plugin for manipulating and adding days to dates

Within my Ruby on Rails application, there is a specific field where users can input a date. The current format for this date value is as follows: $('#search_form_handover_date').val() #returns "15-07-2014 09:00" I am looking to modify this dat ...

Utilizing Jquery to Pass an Optional Function to Another Function

I am currently working on a function that utilizes AJAX to submit data and then displays a dialog indicating whether the process was successful or not. Everything seems to be functioning smoothly, but I now want to add the capability of passing an addition ...

Running tasks in the background with Express.js after responding to the client

Operating as a basic controller, this system receives user requests, executes tasks, and promptly delivers responses. The primary objective is to shorten the response time in order to prevent users from experiencing unnecessary delays. Take a look at the ...

Obtain a value that is not defined

Good day, I am encountering an issue with my data not accepting an undefined value. Below is the code snippet: interface IModalContatos { dados: IContatos; onSave(dados: IContatos): void; onClose(): void; } When passing this data to my modal, I rece ...

Encountering an issue while attempting to extract an ACF field in WordPress using JavaScript

When I write the following code, everything works fine: <script> $(document).ready(function(){ var user_id = '<?php echo get_current_user_id(); ?>'; // This is working var subject = "<?php echo the_field('subject ...

Is it possible for Angular's `HttpClient` to use complex property types in the `.get()` generics aside from just `string` or `number`?

After spending an entire day researching the topic, I've hit a dead end. All my efforts have only led me to discover one thing—omission. None of the information I've come across mentions whether you can utilize non-simple types (such as string ...

JavaScript: The functionality of calling functions through buttons ceases to function once the page is updated without reloading

I am trying to create a program that consists of one HTML page, where I can dynamically update and populate it with different elements using JavaScript. The main feature of the program is a button that remains constant in every version and displays a mod ...