resvg-js icon indicating copy to clipboard operation
resvg-js copied to clipboard

Feature request: support loading fonts with raw data

Open homerjam opened this issue 2 years ago • 17 comments

Hello, thanks for this awesome library - I came across it via svg2img.

Would it be possible to support loading fonts via raw data? It's seems this might be possible using the font library dependency https://github.com/RazrFalcon/fontdb#features

The reason is that on Vercel I can't seem to use fonts because file system access is protected/complicated. I've also tried embedding the font in the svg with font-face/data-uri but this doesn't seem to be supported either.

Thanks

homerjam avatar Apr 25 '22 17:04 homerjam

Yes, this feature is possible and scheduled. We'll find some time to implement it soon.

zimond avatar Apr 26 '22 02:04 zimond

@zimond Hey 👋 Any updates on this? I'm currently struggling to load fonts to my svg as well

snelsi avatar Jun 16 '22 22:06 snelsi

@snelsi This work is very complex and @zimond is being worked on.

yisibl avatar Jun 17 '22 10:06 yisibl

@yisibl @zimond Do you have any rough estimates of when this feature will be released? Thank you!

snelsi avatar Jul 14 '22 09:07 snelsi

@yisibl @zimond Do you have any rough estimates of when this feature will be released? Thank you!

@snelsi just so you know for the future, to illicit a positive response a better way to phase this question would be "is there anything I can do to help with this feature such as providing ideas, coding, testing or monetary support?"

homerjam avatar Jul 14 '22 12:07 homerjam

Never mind. It indeed takes longer time than estimated. There's an open PR #118 addressing this feature. It works now it you manually built the artifacts. So if this is what you really want, you could try the pr and any feedback is welcomed as it dramatically changed the current API design.

zimond avatar Jul 15 '22 02:07 zimond

Hi everyone! I'm having the exact same problem. Everything works on Vercel, except the fonts.

Has anyone found a workaround?

filipedeschamps avatar Jul 21 '22 21:07 filipedeschamps

I found a way to make it work on Vercel 🤝 the above link is working and should show you this:

image

Inside your next.config.js you should add:

  experimental: {
    nftTracing: true,
  },

For example, my current next.config.js

module.exports = {
  pageExtensions: ['public.js'],
  eslint: {
    ignoreDuringBuilds: true,
  },
  experimental: {
    nftTracing: true,
  },
  compiler: {
    styledComponents: true,
  },
  i18n: {
    locales: ['pt-br'],
    defaultLocale: 'pt-br',
  },
};

And then, you can resolve the file path like this:

const { join, resolve } = require('path');

// ...

  const result = await renderAsync(svg, {
    fitTo: {
      mode: 'width',
      value: 1280,
    },
    font: {
      fontFiles: [
        join(resolve('.'), 'fonts', 'Roboto-Regular.ttf'),
        join(resolve('.'), 'fonts', 'Roboto-Bold.ttf'),
        join(resolve('.'), 'fonts', 'NotoEmoji-Bold.ttf'),
      ],
      loadSystemFonts: false,
      defaultFontFamily: 'Roboto',
    },
  });

But, there's still one problem [deprecated, it's working]

Despite that it works 100% on Vercel, I can't make it work on Github Actions.

@homerjam is there any way to make the module more verbose? Thank you.

[edit]

Never mind, it's working.

[edit2]

Implementation is already running in production. It's hosted on Vercel and it's using resvg to create dynamic custom thumbnails of a post, just like Github does, for example:

The post: https://www.tabnews.com.br/filipedeschamps/50-hacks-de-produtividade-escolhidos-pela-internet

The thumbnail: https://www.tabnews.com.br/api/v1/contents/filipedeschamps/50-hacks-de-produtividade-escolhidos-pela-internet/thumbnail

filipedeschamps avatar Jul 21 '22 21:07 filipedeschamps

@filipedeschamps do you host the fonts locally? and how did you apply font to each text? font-family="Roboto"?

zernonia avatar Jul 28 '22 15:07 zernonia

do you host the fonts locally?

Yes, in the path /fonts/Roboto-Regular.ttf for example. That's why I can resolve them like this:

join(resolve('.'), 'fonts', 'Roboto-Regular.ttf'),

and how did you apply font to each text? font-family="Roboto"?

No, it's being applied globally:

defaultFontFamily: 'Roboto',

filipedeschamps avatar Jul 28 '22 16:07 filipedeschamps

Any updates on this? I've tried @filipedeschamps solution, but without any success.

My font is located at public/_static/font/Inter-VariableFont_slnt,wght.ttf. I've enabled outputFileTracing: true in next.config.js, and then tried creating the path using both resolve('.') and process.cwd(), but neither solutions worked.

font: {
  fontFiles: [resolve('.'), "_static/font", "Inter-VariableFont_slnt,wght.ttf")],
  // fontFiles: [join(process.cwd(), "_static/font", "Inter-VariableFont_slnt,wght.ttf")],
  defaultFontFamily: "Inter",
  loadSystemFonts: false,
}

I've also tried forgetting about custom fonts and just using system fonts but that didn't work either. On local machine everything is fine, but on vercel deployments text is not rendered.

font: {
  loadSystemFonts: true,
}

During local development I just used to have an absolute path, which works perfectly fine, but obviously breaks during deployments...

font: {
  fontFiles: ["./public/_static/font/Inter-VariableFont_slnt,wght.ttf"],
  defaultFontFamily: "Inter",
  loadSystemFonts: false,
}

I've also inspected build output in Vercel and I can see my font file as part of it, but none of the path resolutions from above would work during deployments.

CleanShot 2023-04-10 at 12 10 29

pondorasti avatar Apr 10 '23 19:04 pondorasti

I'm sorry this is currently halted. Maybe #217 could fit your needs? If so we will try to merge that PR this week. @Pondorasti

zimond avatar Apr 13 '23 03:04 zimond

I think that would do it @zimond! Looking forward to the #217 changes 🤗

pondorasti avatar Apr 13 '23 17:04 pondorasti

Any updates on this? I've tried @filipedeschamps solution, but without any success.

My font is located at public/_static/font/Inter-VariableFont_slnt,wght.ttf. I've enabled outputFileTracing: true in next.config.js, and then tried creating the path using both resolve('.') and process.cwd(), but neither solutions worked.

font: {
  fontFiles: [resolve('.'), "_static/font", "Inter-VariableFont_slnt,wght.ttf")],
  // fontFiles: [join(process.cwd(), "_static/font", "Inter-VariableFont_slnt,wght.ttf")],
  defaultFontFamily: "Inter",
  loadSystemFonts: false,
}

I've also tried forgetting about custom fonts and just using system fonts but that didn't work either. On local machine everything is fine, but on vercel deployments text is not rendered.

font: {
  loadSystemFonts: true,
}

During local development I just used to have an absolute path, which works perfectly fine, but obviously breaks during deployments...

font: {
  fontFiles: ["./public/_static/font/Inter-VariableFont_slnt,wght.ttf"],
  defaultFontFamily: "Inter",
  loadSystemFonts: false,
}

I've also inspected build output in Vercel and I can see my font file as part of it, but none of the path resolutions from above would work during deployments.

CleanShot 2023-04-10 at 12 10 29

Did you manage to find a solution in the end?

arkaydeus avatar Apr 29 '23 14:04 arkaydeus

OK, so I got it to work. I'm using Next 13. Here's how:

Put the fonts in the root of your repo in a folder called fonts. Strangely this does not show up in the build output. I tried creating a public/fonts folder and that did show up, but the files couldn't be loaded and it didn't work.

This is the font section of my opts:

  font: {
    fontFiles: [
      join(process.cwd(), 'fonts', 'OpenSans-Medium.ttf'),
      join(process.cwd(), 'fonts', 'RobotoMono-Regular.ttf')
    ], // Load custom fonts.
    loadSystemFonts: false, // It will be faster to disable loading system fonts.
    defaultFontFamily: 'Roboto Mono' // Set default font family.
  }
  

next.config.js is as follows:

const nextConfig = {
  reactStrictMode: true,
  experimental: {
    nftTracing: true
  },
  outputFileTracing: true
}

Successfully picking up the fonts on the Vercel side and rendering them ok!

Working project here if you're interested: https://github.com/arkaydeus/vercel-svg-png

arkaydeus avatar Apr 29 '23 14:04 arkaydeus

thanks for sharing your findings @arkaydeus, I've got it working too 🤗! Looks like the missing piece was to place the fonts at root instead of the /static directory.

Put the fonts in the root of your repo in a folder called fonts. Strangely this does not show up in the build output.

No kidding, it breaks the Vercel dashboard output page for me. 🤣


Btw, nftTracing is not really needed. It's not even part of the config spec if you look at the typings. I believe nftTracing got renamed to outputFileTracing when it made it out of experimental.

const nextConfig = {
   reactStrictMode: true,
-  experimental: {
-    nftTracing: true
-  },
   outputFileTracing: true
}

pondorasti avatar May 06 '23 00:05 pondorasti

I'm loading fonts from Fontsource using the wasm version. Not sure if that would fix the problems folks on Vercel are running into, at least temporarily.

AndrewAskins avatar Jun 10 '24 17:06 AndrewAskins