Original article: How to Use SVG Icons in React with React Icons and Font Awesome

Emplear iconos es una manera de comunicar visualmente conceptos y significados sin necesidad de palabras. Esto podría usarse para una clasificación, una acción o incluso una advertencia.

¿Cómo podemos añadir iconos a nuestras aplicaciones de React para mejorar nuestro mensaje visual usando SVG?

¿Qué es SVG?

SVG son las siglas en inglés de gráficos vectoriales escalables (Scalable Vector Graphics). Es un formato de archivo  –basado en un lenguaje de marcado similar al XML– que permite a programadores y diseñadores crear imágenes vectoriales usando definiciones de rutas.

¿Qué hace que SVG sea genial para la web?

SVG nació para la web. Es un estándar abierto creado por el W3C para proveer de una mejor manera de añadir imágenes a la web. Si abres un archivo SVG en tu ordenador, puede que te sorprenda ver que... ¡Todo es código!

Esto influye en el reducido tamaño del archivo. Normalmente, cuando se utiliza un SVG, te puedes aprovechar de su menor tamaño en comparación con los archivos de imagen, más grandes, que podrían ser necesarios para ofrecer la misma alta resolución.

Además, ya que estamos definiendo los SVG como rutas, pueden agrandarse o reducirse tanto como queramos. Esto los hace aún más flexibles para su uso en la web, especialmente cuando se trata de crear experiencias adaptativas.

¿Qué vamos a crear?

Primero pasaremos a utilizar un paquete llamado react-icons que nos permitirá importar, de una manera fácil y directa, los iconos de conjuntos populares de iconos como Font Awesome.

También echaremos un vistazo a cómo podemos añadir manualmente los archivos SVG a nuestra aplicación; copiando directamente el código de un archivo SVG dentro de un nuevo componente.

Parte 0: Creando una aplicación de React

Para este tutorial, puedes utilizar cualquier framework de React que desees, ya sea Create React App o Next.js. Incluso puedes usar un proyecto existente.

Como no necesitamos nada especial para añadir nuestros iconos, voy a usar create-react-app.

Para ir empezando con Create React App, puedes crear un nuevo proyecto utilizando uno de los comandos siguientes en tu terminal:

yarn create react-app [nombre-de-tu-proyecto]

# o bien

npx create-react-app [nombre-de-tu-proyecto]

Nota: reemplaza [nombre-de-tu-proyecto] por el nombre que quieres emplear para tú proyecto. Yo utilizaré my-svg-icons.

Cuando tengas creada tu aplicación nueva, o tengas ya una aplicación, ¡estaremos listos para continuar!

new-create-react-app
Nueva aplicación de React

Parte 1: Añadiendo iconos SVG con react-icons

Añadiendo react-icons a tu proyecto

Para poder empezar con react-icons lo instalaremos primero en nuestro proyecto.

Ejecuta el comando siguiente dentro de tu proyecto:

yarn add react-icons
# o bien
npm install react-icons --save

Una vez completado el proceso, deberíamos poder utilizarlo en nuestro proyecto.

Seleccionando los iconos del proyecto

Una de las cosas interesantes de react-icons es una biblioteca extensa que pone a disposición dentro de un paquete individual.

No solo tenemos inmediatamente accesible Font Awesome, sino también los repositorios de GitHub, Octicons, Heroicons, Material Design Icons, y un montón más.

react-icons-heroicons
La librería Heroicons en react-icons

A la hora de elegir los iconos prácticamente podrías usar el que tú quieras en cualquier momento. Dicho esto, te recomiendo que intentes ser coherente en la apariencia de tus iconos.

Si para tu sitio web utilizas principalmente Font Awesome, podría parecer un poco extraño e incoherente si empezases a añadir Flat Color Icons a la mezcla. En última instancia, lo que quieres es ofrecer una experiencia en la que la gente sea capaz de identificar fácilmente los patrones que has creado.  

Utilizando react-icons en tu proyecto

Una vez que hayas encontrado los iconos que quieres usar, ya podemos añadirlos a nuestro proyecto.

La página web de react-icons nos facilita la búsqueda del nombre del icono que queremos utilizar e importar a nuestro proyecto.

Por ejemplo, si quisiéramos utilizar el icono del cohete [rocket en inglés] de Font Awesome nos posicionaríamos en la barra lateral, nos desplazamos hasta Font Awesome, buscamos "cohete" en la página (con la ayuda de CMD + F, o CTRL + F) y, finalmente, clicamos sobre el icono; lo que copiará su nombre a tú portapapeles.

font-awesome-rocket
Icono de cohete en la librería Font Awesome

También podemos buscar "cohete" en el formulario de búsqueda de la parte superior izquierda de la página; lo que nos mostraría el resultado "cohete" en todos los conjuntos de iconos existentes.

react-icons-rocket
Iconos de cohetes en la librería react-icons

Ahora ya podemos importar ese icono dentro de nuestro proyecto. Al igual que en las instrucciones de la parte superior de la página de react-icons, queremos importar ese icono específico react-icons/fa al que se refiere al módulo Font Awesome de react-icons.

En la parte superior del archivo en el que quieras importar el icono añade lo siguiente. Si usas create-react-app para un proyecto nuevo, puedes añadirlo al principio del archivo src/App.js.

import { FaRocket } from 'react-icons/fa';

Para probarlo, sustituyamos el logo de React por nuestro icono.

Elimina el elemento <img y sustitúyelo por:

<FaRocket />

Y si recargamos la página, ¡podremos ver nuestro cohete!

create-react-app-rocket-icon
Rocket icon in React app

Sin embargo, nuestro cohete no gira como el logo de React, así que vamos a arreglarlo.

Añade la clase .App-logo al componente FaRocket:

<FaRocket className="App-logo" />

¡Y ahora el cohete debería estar girando!

create-react-app-rocket-spin
Spinning rocket icon in React app

Pero también es un poco pequeño. Si miramos dentro de src/App.css estamos estableciendo la altura de .App-logo a 40vmin. Si bien eso funciona, para que nuestro icono llene el espacio, le tenemos que proporcionar también un ancho.

Para añadir un ancho [width], agrega el código siguiente a la clase CSS .App-logo:

width: 40vmin;

Aunque ahora probablemente sea un poco demasiado grande, ¡ya tenemos nuestro icono y un tamaño más apropiado!

create-react-app-icon-rocket-spin-large
Increased size of spinning rocket icon in React app

Sigue el proceso en el commit del repositorio.

Parte 2: Añadiendo manualmente archivos SVG a un componente de React

A veces, no querrás añadir una nueva biblioteca solo para conseguir un icono. En ocasiones, se trata de un icono personalizado que no está disponible en una biblioteca pública.

Afortunadamente con React, podemos crear un nuevo componente SVG con bastante facilidad que nos permite añadir nuestros iconos SVG personalizados donde queramos.

Primero, busquemos un icono.

Aunque todos los iconos de Heroicons están disponibles dentro de react-icons, vamos a utilizarlo como ejemplo, ya que es fácil de encontrar y copiar algo de código SVG.

Ve a heroicons.com y busca por un icono que te gustaría usar para este ejemplo. Yo utilizaré "globo terráqueo" [globe].

Después de encontrar el icono que quieres, pasa el ratón por encima del mismo y verás las opciones para copiarlo como SVG o JSX. Pulsa copiar como JSX.

heroicons-copy-svg
Copy as JSX in Heroicons

Con ese icono ya copiado, crea un nuevo archivo bajo src llamado Globe.js.

Dentro de ese archivo, crearemos un nuevo componente llamado "Globo" y pegaremos nuestro código SVG dentro del mismo.

import React from 'react';

const Globo = () => {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
    </svg>
  )
}

export default Globo;

Nota: al copiar SVG normal dentro de un componente de React, puede que no funcione "tal cual es". A veces, los archivos SVG incluyen clases CSS o atributos que no son válidos con JSX.

Si te encuentras con errores, intenta arreglar los atributos y mira la consola del navegador para ver los errores y las advertencias que React arroja. Como copiamos el icono como JSX, conseguimos hacerlo funcionar de inmediato.

Ahora, vuelve a src/App.js e importa nuestro nuevo componente:

import Globo from './Globo';

A continuación, podemos sustituir el icono del cohete por nuestro nuevo componente:

<Globo />

Y si abrimos nuestro navegador, ¡podremos ver nuestro globo terráqueo!

create-react-app-globe-large
Icono enorme de un globo terráqueo en la aplicación de React

Aunque es un poco grande.

Queremos aplicar nuestra clase .App-logo a nuestro componente Globo, así que necesitamos actualizar dicho componente para que reciba una prop ('propiedad') className.

Vuelve a src/Globo.js, y añade la propiedad className como argumento:

const Globo = ({ className }) => {

Luego, añade una nueva propiedad con esa className prop ('propiedad') al componente <svg:

<svg className={className}

Ahora, podemos actualizar nuestro componente Globo en src/App.js para incluir esa clase:

<Globo className="App-logo" />

Y si recargamos la página, podremos ver que nuestro logotipo, con el tamaño correcto, está de vuelta y ¡vuelve a girar!

create-react-app-globe-icon-spinning
Icono giratorio de un globo terráqueo de tamaño normal en una aplicación de React

Sigue el proceso en el commit del repositorio.

¿Por qué no lo incluimos como un archivo de imagen?

Aunque podemos incluir el icono como un archivo de imagen, tal y como hace React en el código predeterminado por create-react-app, se obtienen algunas ventajas al añadir nuestros archivos SVG en línea.

Por un lado, cuando añadimos el SVG en línea, podremos acceder a las distintas rutas con las propiedades CSS. Esto nos da más flexibilidad para personalizarlo dinámicamente.

Y, por otro lado, proporcionará menos peticiones HTTP. El navegador sabrá cómo cargar ese archivo SVG, así que no necesitaremos molestar al navegador para que solicite ese archivo para incluirlo en la página.

Dicho esto, sigue siendo una opción válida para añadir un archivo SVG a la página.