Closed ties-v closed 2 years ago
Using the local font from npm is one of the methods described in MUI's docs: https://mui.com/components/typography/#install-with-npm
I would expect this to work out of the box with Remix.
I found the following workaround on the Remix Discord (credit goes to @kiliman): https://discord.com/channels/770287896669978684/940920958540197889/941007998388690985
For those who don't want to / can't follow the Discord link, add this to your package.json
to copy the font files to the bulid folder (change poppins
to the name of the font you use):
"build": "remix build && npm run install:fonts",
"postinstall": "remix setup node && npm run install:fonts",
"install:fonts": "rsync -r node_modules/@fontsource/poppins/files/ public/build/_assets/files/"
If you are using PrimeIcons with PrimeReact then the script is...
Unix:
"build": "remix build && npm run install:fonts",
"postinstall": "remix setup node && npm run install:fonts",
"install:fonts": "rsync -r node_modules/primeicons/fonts/ public/build/_assets/fonts/",
Windows:
npm install copyfiles
"build": "remix build && npm run install:fonts",
"postinstall": "remix setup node && npm run install:fonts",
"install:fonts": "copyfiles -u 3 "./node_modules/primeicons/fonts/*" ./public/build/_assets/fonts/",
Copying font files manually does not work with the latest version (1.6.4) anymore. Font file references are now cache busted.
Is there a way to disable cache busting for css or make remix copy the font files?
looking into this a bit, looks like esbuild doesn't copy imports/urls from .css
files if the loader is set to 'file'
edit: made an example repo - https://github.com/mcansh/playground-1658515042024/tree/main
i did manage to get this working using postcss
as a interim step in the build process
// ./postcss.config.js
const path = require("node:path");
const fse = require("fs-extra");
module.exports = {
plugins: {
"postcss-import": {},
"postcss-url": {
url: (asset) => {
let { absolutePath } = asset;
let basename = path.basename(absolutePath);
let outDir = path.join(
__dirname,
"public",
"build",
"_assets",
"fonts"
);
let destpath = path.join(outDir, basename);
if (!fse.pathExistsSync(destpath)) {
fse.copySync(absolutePath, destpath);
}
return "/" + path.join("build", "_assets", "fonts", basename);
},
},
},
};
// ./styles/index.css
@import "@fontsource/aguafina-script/index.css";
using npm-run-all
to run both remix and postcss in one tab
"scripts": {
"dev:css": "postcss ./styles/index.css --output ./app/styles/index.css --watch",
"dev:remix": "remix dev",
"dev": "run-p dev:*"
}
// ./app/routes/root.jsx
import fontStyleUrl from './styles/index.css';
"build": "remix build && npm run install:fonts", "postinstall": "remix setup node && npm run install:fonts", "install:fonts": "copyfiles -u 3 "./node_modules/primeicons/fonts/*" ./public/build/_assets/fonts/",
So this method works when running remix build
but does not when running remix dev
. For some reason when running remix dev
there are two build
directories generated: one in the public
directory and another in the root of the repo (which looks like a duplicate of the directory in the public
directory..).
My fix for this was to add a prestart
script like so:
"prestart": "npm run install:fonts",
"start": "remix dev"
if you use npm run dev
instead, it would look like this:
"predev": "npm run install:fonts",
"dev": "remix dev"
UPDATE:
Also, I used cpy-cli instead of copyfiles so the install:fonts
script would look like this for the above scenario:
"install:fonts": "cpy './node_modules/primeicons/fonts/*' public/build/_assets/fonts/"
I think this should be handled by the framework and not by developers using the remix.
I was wondering, so I had a look and the loader for the css is actually a "file"
type also mentioned in the https://github.com/remix-run/remix/issues/185#issuecomment-1007139460.
After change to "css"
as esbuild should to cover it I see this in the console.
Remix App Server started at http://localhost:3001 (http://172.20.10.2:3001)
GET / 200 - - 143.124 ms
GET /[object%20Object] 404 - - 9.569 ms
Otherwise I see
...
GET /build/_assets/fonts/primeicons.ttf 404 - - 6.513 ms
GET /build/_assets/fonts/primeicons.woff 404 - - 5.325 ms
I think that esbuild has some problem here or it is used on way which doesn't allow to parse css properly.
I think this should be handled by the framework and not by developers using the remix.
definitely, i took a quick look at this a bit ago - never opened an issue on esbuild yet, but looks like if you use a file
loader on a css file it doesn't copy over the url()
assets in that file, however if you use a css
loader they are copied, but then css file itself is not hashed and the url doesn't get replaced in the build file
looks like this is what we need to do: https://github.com/evanw/esbuild/issues/1757#issuecomment-963133064 looking into it :)
@mcansh I've created a plugin which (hopefully) does the job.. I've tried to touch as less as possible and recycle as many build options as possible #4130
@mcansh I've created a plugin which (hopefully) does the job.. I've tried to touch as less as possible and recycle as many build options as possible #4130
awesome! i'm gonna pull this and check it out ❤️
We're actually rebuilding the Fontsource website with Remix so this is huge. Thank you so much for giving up your time for this @mcansh and @KingSora!
🤖 Hello there,
We just published version v0.0.0-nightly-a0823ed-20221015
which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!
Thanks!
Fixed in 1.7.3, thank you @KingSora 🎉
copyfiles
Hi Friends !!! In my case, the development server sources did not load... I share in this answer my solution (in Remix App FullStack Framework):
// in your root project:
yarn add copyfiles
copyfiles library docs link
// in your package.json file allocated in your root project:
...previus lines
"dev": "run-p dev:*",
"dev:css": "npm run generate:css -- --watch",
"dev:remix": "cross-env NODE_ENV=development binode --require ./mocks -- @remix-run/dev:remix dev",
"dev:fonts": "rsync -r public/fonts/ public/build/_assets/fonts/",
...next lines
// in your css file to load in your route: 3) add your @font-face css rules in your css file loaded from your route: For example in my case:
@font-face {
font-family: 'ChekoFontBold';
src: local('ChekoFont-Bold'),
url('fonts/Cheko Fonts/Web/ChekoFont/ChekoFont-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/Cheko Fonts/Web/ChekoFont/ChekoFont-Bold.woff') format('woff'), /* Modern Browsers */
url('fonts/Cheko Fonts/Web/ChekoFont/ChekoFont-Bold.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/Cheko Fonts/Web/ChekoFont/ChekoFont-Bold.svg#BloggerSans') format('svg'); /* Legacy iOS */
font-style: normal;
font-weight: normal;
text-rendering: optimizeLegibility;
}
.section-title { font-family: "ChekoFontBold" !important; text-align: center; font-size: 2rem !important; }
________________________________________
// in your css file to load in your route:
4) add your rule css className in your tsx or jsx file loaded from your route:
For example in my case:
import React from 'react';
export default function About() {
return (<div className={section
}>
<h1 className={section-title
}>{"Good luck !"}
Its worked for me !!
Good luck !
@sergioarieljuarez if 1.7.3 didn't work for you here, please open a new issue and provide a public repository reproducing the problem 🙏
hi, any tip on how to get the url for the hashed font file referenced in the css file? I'm trying to preload the font via route module's links
function, but esbuild throws an error when importing the font file from node_modules.
@universse please ask support questions in the Discussions tab.
What version of Remix are you using?
1.1.1
What version of Node are you using? Minimum supported version is 14.
14.18.1
Steps to Reproduce
Example on stackblitz.com
yarn create remix
to create a new remix project.yarn add @fontsource/aguafina-script
root.tsx
: (source)export let links: LinksFunction = () => { return [ { rel: "stylesheet", href: fontStyleUrl }, { rel: "stylesheet", href: mainStyleUrl } ] } // ...