Como adicionar fontes a projetos baseados em criar e reagir aplicativos?

177

Estou usando o create-react-app e prefiro não eject.

Não está claro para onde as fontes importadas via @ font-face e carregadas localmente devem ir.

Ou seja, estou carregando

@font-face {
  font-family: 'Myriad Pro Regular';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Regular'), url('MYRIADPRO-REGULAR.woff') format('woff');
}

Alguma sugestão?

- EDITAR

Incluindo a essência a que Dan se refere em sua resposta

  Client git:(feature/trivia-game-ui-2)  ls -l public/static/fonts
total 1168
-rwxr-xr-x@ 1 maximveksler  staff  62676 Mar 17  2014 MYRIADPRO-BOLD.woff
-rwxr-xr-x@ 1 maximveksler  staff  61500 Mar 17  2014 MYRIADPRO-BOLDCOND.woff
-rwxr-xr-x@ 1 maximveksler  staff  66024 Mar 17  2014 MYRIADPRO-BOLDCONDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  66108 Mar 17  2014 MYRIADPRO-BOLDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  60044 Mar 17  2014 MYRIADPRO-COND.woff
-rwxr-xr-x@ 1 maximveksler  staff  64656 Mar 17  2014 MYRIADPRO-CONDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  61848 Mar 17  2014 MYRIADPRO-REGULAR.woff
-rwxr-xr-x@ 1 maximveksler  staff  62448 Mar 17  2014 MYRIADPRO-SEMIBOLD.woff
-rwxr-xr-x@ 1 maximveksler  staff  66232 Mar 17  2014 MYRIADPRO-SEMIBOLDIT.woff
  Client git:(feature/trivia-game-ui-2)  cat src/containers/GameModule.css
.GameModule {
  padding: 15px;
}

@font-face {
  font-family: 'Myriad Pro Regular';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Regular'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-REGULAR.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Condensed';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-COND.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Semibold Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Semibold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Semibold';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Semibold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLD.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Condensed Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-CONDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold Condensed Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCONDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold Condensed';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCOND.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLD.woff') format('woff');
}
Maxim Veksler
fonte
2
Você verificou a seção "Adicionando fontes" em seu Guia do usuário?
Dan Abramov
2
@ DanAbramov eu tenho, a recomendação é importar a fonte. Mas sinto que não está claro (pelo menos não para mim) sobre como isso deve ser feito na prática. Nesse meio tempo, eu fiz isso gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5 e parece funcionar (alertas de pacotes da Web se não conseguir encontrar um arquivo de fonte), mas tenho certeza de que não é a solução ideal e um exemplo ou tê-lo documentado aqui ajudaria. ty por estender a mão!
precisa saber é o seguinte
2
Eu respondi. Sua abordagem parece errada para mim: %PUBLIC_URL%não pode funcionar (e é desnecessário) em um arquivo CSS. Além disso, conforme descrito no guia, você deve usar importações JS em quase todos os casos, não na pasta pública.
Dan Abramov 16/01
Existe algum utilitário / pacote para verificar a pasta especificada em busca de fontes e gerar o arquivo de script com todas as variações de fonte? É tedioso escrever tudo manualmente
helloworld

Respostas:

290

Existem duas opções:

Usando importações

Esta é a opção sugerida. Ele garante que suas fontes passem pelo pipeline de construção, obtenham hashes durante a compilação, para que o cache do navegador funcione corretamente e que você obtenha erros de compilação se os arquivos estiverem ausentes.

Conforme descrito em “Adicionando imagens, fontes e arquivos” , é necessário ter um arquivo CSS importado do JS. Por exemplo, por padrão, src/index.jsimportações src/index.css:

import './index.css';

Um arquivo CSS como esse passa pelo pipeline de construção e pode fazer referência a fontes e imagens. Por exemplo, se você inserir uma fonte src/fonts/MyFont.woff, index.csspoderá incluir isso:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(./fonts/MyFont.woff) format('woff');
}

Observe como estamos usando um caminho relativo começando com ./. Essa é uma notação especial que ajuda o pipeline de construção (desenvolvido pela Webpack) a descobrir esse arquivo.

Normalmente isso deve ser suficiente.

Usando publicpasta

Se, por algum motivo, você preferir não usar o pipeline de compilação, e fazê-lo da “maneira clássica”, você pode usar a publicpasta e colocar suas fontes lá.

A desvantagem dessa abordagem é que os arquivos não recebem hashes quando você compila para produção, portanto, é necessário atualizar os nomes deles sempre que os alterar, ou os navegadores armazenarão em cache as versões antigas.

Se você quiser fazer dessa maneira, coloque as fontes em algum lugar da publicpasta, por exemplo, em public/fonts/MyFont.woff. Se você seguir essa abordagem, também deverá colocar os arquivos CSS na publicpasta e não importá-los do JS, pois a mistura dessas abordagens será muito confusa. Então, se você ainda quiser fazer isso, terá um arquivo como public/index.css. Você precisaria adicionar manualmente <link>a esta folha de estilo em public/index.html:

<link rel="stylesheet" href="%PUBLIC_URL%/index.css">

E dentro dele, você usaria a notação CSS regular:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(fonts/MyFont.woff) format('woff');
}

Observe como estou usando fonts/MyFont.woffo caminho. Isso ocorre porque index.cssestá na publicpasta para que seja veiculado a partir do caminho público (geralmente é a raiz do servidor, mas se você implantar no GitHub Pages e definir seu homepagecampo como http://myuser.github.io/myproject, ele será veiculado /myproject). No entanto, fontstambém estão na publicpasta, então eles serão exibidos fontsrelativamente (um http://mywebsite.com/fontsou outro http://myuser.github.io/myproject/fonts). Portanto, usamos o caminho relativo.

Observe que, como estamos evitando o pipeline de compilação neste exemplo, ele não verifica se o arquivo realmente existe. É por isso que eu não recomendo essa abordagem. Outro problema é que nosso index.cssarquivo não é compactado e não possui hash. Portanto, será mais lento para os usuários finais, e você corre o risco de os navegadores colocarem em cache as versões antigas do arquivo.

 Que maneira de usar?

Siga o primeiro método ("Usando importações"). Eu apenas descrevi o segundo, já que foi isso que você tentou fazer (a julgar pelo seu comentário), mas ele tem muitos problemas e só deve ser o último recurso quando você está contornando algum problema.

Dan Abramov
fonte
5
um exemplo na documentação seria útil, eu também estava um pouco confuso
Tom
2
Eu descobri que eu realmente tive que usar a url ./fonts/Myfont.woff e não ./Myfont.woff
th3morg
57
Se alguém estiver adicionando uma ttffonte, você deve fornecer, em truetypevez de ttfcomo parâmetro, o format* .
milkersarac
3
@milkersarac você é o melhor!
João Vilaça 23/03
19
Seguindo @milkersarac, se você estiver usando, otfprecisará colocar opentype.
Karl Taylor
46

Aqui estão algumas maneiras de fazer isso:

1. Importando fonte

Por exemplo, para usar o Roboto, instale o pacote usando

yarn add typeface-roboto

ou

npm install typeface-roboto --save

No index.js:

import "typeface-roboto";

Existem pacotes npm para muitas fontes de código aberto e a maioria das fontes do Google. Você pode ver todas as fontes aqui . Todos os pacotes são desse projeto .

2. Para fontes hospedadas por terceiros

Por exemplo, fontes do Google, você pode acessar fonts.google.com, onde pode encontrar links que podem ser colocados no seupublic/index.html

captura de tela de fonts.google.com

Vai ser como

<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">

ou

<style>
    @import url('https://fonts.googleapis.com/css?family=Montserrat');
</style>

3. Baixando a fonte e adicionando-a ao seu código fonte.

Faça o download da fonte. Por exemplo, para fontes do google, você pode ir para fonts.google.com . Clique no botão de download para baixar a fonte.

Mova a fonte para o fontsdiretório em seu srcdiretório

src
|
`----fonts
|      |
|      `-Lato/Lato-Black.ttf
|       -Lato/Lato-BlackItalic.ttf
|       -Lato/Lato-Bold.ttf
|       -Lato/Lato-BoldItalic.ttf
|       -Lato/Lato-Italic.ttf
|       -Lato/Lato-Light.ttf
|       -Lato/Lato-LightItalic.ttf
|       -Lato/Lato-Regular.ttf
|       -Lato/Lato-Thin.ttf
|       -Lato/Lato-ThinItalic.ttf
|
`----App.css

Agora App.css, adicione este

@font-face {
  font-family: 'Lato';
  src: local('Lato'), url(./fonts/Lato-Regular.otf) format('opentype');
}

@font-face {
    font-family: 'Lato';
    font-weight: 900;
    src: local('Lato'), url(./fonts/Lato-Bold.otf) format('opentype');
}

@font-face {
    font-family: 'Lato';
    font-weight: 900;
    src: local('Lato'), url(./fonts/Lato-Black.otf) format('opentype');
}

Para o ttfformato, você precisa mencionar format('truetype'). Para woff,format('woff')

Agora você pode usar a fonte nas classes.

.modal-title {
    font-family: Lato, Arial, serif;
    font-weight: black;
}

4. Usando o pacote web-font-loader

Instale o pacote usando

yarn add webfontloader

ou

npm install webfontloader --save

Em src/index.js, você pode importar isso e especificar as fontes necessárias

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});
sudo bangbang
fonte
2
--save é o padrão com npm 5 (2017)
NattyC 10/07/19
Obrigado pelo comentário @Natalie, fico feliz que a NPM tenha feito essa alteração.
Sudo bangbang
@sudobangbang Obrigado, a solução 3 funcionou para mim. No entanto - existe uma maneira de não colocar a fontspasta em baixo src, mas em publicvez disso? Eu tentei, mas parece que não é permitido ...
Yossi Vainshtein 28/01
@YossiVainshtein, acho que não. Como você está usando as fontes no App.css, elas também devem ser compiladas.
sudo bangbang 28/01
For ttf format, you have to mention format('truetype'). For woff, format('woff')fez isso por mim! obrigado!
Joseph Briggs
7
  1. Acesse o Google Fonts https://fonts.google.com/
  2. Selecione sua fonte como na imagem abaixo:

insira a descrição da imagem aqui

  1. Copie e cole esse URL na nova guia. Você obterá o código css para adicionar essa fonte. Nesse caso, se você for para

https://fonts.googleapis.com/css?family=Spicy+Rice

Ele será aberto assim:

insira a descrição da imagem aqui

4, Copie e cole esse código no seu style.css e simplesmente comece a usar essa fonte assim:

      <Typography
          variant="h1"
          gutterBottom
          style={{ fontFamily: "Spicy Rice", color: "pink" }}
        >
          React Rock
        </Typography>

Resultado:

insira a descrição da imagem aqui

Hitesh Sahu
fonte
1
Em muitos casos (por exemplo, redes corporativas), o acesso à CDN externa é bloqueado pelo firewall e esse método, embora correto, pode não funcionar. Temos várias VLANs em nossa organização e, exceto a TI e poucas outras, todas as VLANs bloqueiam o acesso externo à CDN, o que também significa que a CDN de conteúdo do Google também está bloqueada. Estive lá, fiz isso.
AnBisw
2

Você pode usar o módulo WebFont , que simplifica bastante o processo.

render(){
  webfont.load({
     custom: {
       families: ['MyFont'],
       urls: ['/fonts/MyFont.woff']
     }
  });
  return (
    <div style={your style} >
      your text!
    </div>
  );
}
Delfino
fonte
0

Eu estava cometendo erros assim.

@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext";
@import "https://use.fontawesome.com/releases/v5.3.1/css/all.css";

Funciona corretamente dessa maneira

@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext);
@import url(https://use.fontawesome.com/releases/v5.3.1/css/all.css);
Yasin UYSAL
fonte
0

Passei a manhã inteira resolvendo um problema semelhante depois de ter abordado essa questão da pilha. Usei a primeira solução de Dan na resposta acima como ponto de partida.

Problema

Eu tenho um ambiente de desenvolvimento (esta na minha máquina local), preparação e produção. Meus ambientes de preparação e produção vivem no mesmo servidor.

O aplicativo é implantado na preparação acmeserver/~staging/note-taking-appe a versão de produção fica em acmeserver/note-taking-app(culpa de TI).

Todos os arquivos de mídia, como fontes, estavam carregando perfeitamente no dev (ou seja, react-scripts start).

No entanto, quando eu criei e enviei compilações de preparação e produção, enquanto o .csse.js arquivos estavam carregando corretamente, as fontes não estavam. O .cssarquivo compilado parecia ter um caminho correto, mas a solicitação http do navegador estava recebendo um caminho muito errado (mostrado abaixo).

O main.fc70b10f.chunk.cssarquivo compilado :

@font-face {
  font-family: SairaStencilOne-Regular;
  src: url(note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf) ("truetype");
}

A solicitação http do navegador é mostrada abaixo. Observe como ele está sendo adicionado /static/css/quando o arquivo de fonte está localizado/static/media/ , além de duplicar a pasta de destino. Eu descartei a configuração do servidor como a culpada.

Também Refererestá parcialmente em falta.

GET /~staging/note-taking-app/static/css/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf HTTP/1.1
Host: acmeserver
Origin: http://acmeserver
Referer: http://acmeserver/~staging/note-taking-app/static/css/main.fc70b10f.chunk.css

O package.jsonarquivo tinha a homepagepropriedade definida como ./note-taking-app. Isso estava causando o problema.

{
  "name": "note-taking-app",
  "version": "0.1.0",
  "private": true,
  "homepage": "./note-taking-app",
  "scripts": {
    "start": "env-cmd -e development react-scripts start",
    "build": "react-scripts build",
    "build:staging": "env-cmd -e staging npm run build",
    "build:production": "env-cmd -e production npm run build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
  //...
}

Solução

Isso foi por muito tempo - mas a solução é:

  1. mudar o PUBLIC_URL variável env dependendo do ambiente
  2. remova a homepagepropriedade do package.jsonarquivo

Abaixo está o meu .env-cmdrcarquivo. Uso .env-cmdrcmais do que o normal .envporque mantém tudo junto em um arquivo.

{
  "development": {
    "PUBLIC_URL": "",
    "REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
  },
  "staging": {
    "PUBLIC_URL": "/~staging/note-taking-app",
    "REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
  },
  "production": {
    "PUBLIC_URL": "/note-taking-app",
    "REACT_APP_API": "http://acmeserver/note-taking-app/api"
  }
}

O roteamento via também react-router-domfunciona bem - basta usar a PUBLIC_URLvariável env como basenamepropriedade.

import React from "react";
import { BrowserRouter } from "react-router-dom";

const createRouter = RootComponent => (
  <BrowserRouter basename={process.env.PUBLIC_URL}>
    <RootComponent />
  </BrowserRouter>
);

export { createRouter };

A configuração do servidor está definida para rotear todas as solicitações para o ./index.htmlarquivo.

Finalmente, eis a main.fc70b10f.chunk.cssaparência do arquivo compilado após a implementação das alterações discutidas.

@font-face {
  font-family: SairaStencilOne-Regular;
  src: url(/~staging/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf)
    format("truetype");
}

Material de leitura

puiu
fonte