Open wavedeck opened 11 months ago
For reference, i managed to make Font-Awesome SVG+JS work on the client side by using @fortawesome/fontawesome-svg-core
in my layout component. However, this results in a small flash since the client needs to execute the javascript before an icon appears. It would be best to handle svg-inlining on the server side to minimize this behavior.
This is how to use SVG+JS client-side in Astro:
src/layouts/Layout.astro
component add the styles / scripts of @fortawesome/fontawesome-svg-core
---
// load the core stylesheet on the server side,
// so astro can bundle, optimize and serve it.
import '@fortawesome/fontawesome-svg-core/styles.css'
---
<!doctype html>
{/ Add a client side script for loading Font-Awesome /}
2. and then in your `src/pages/index.astro` add the icon:
```astro
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<h1>Hello World</h1>
{/* add the icon to your page. it will automatically be replaced client-side */}
<i class="fas fa-phone"></i>
</Layout>
I also just tested dom.i2svg()
instead of .watch() and can confirm it working even for deeply nested pages, since all astro does is bundle the script using vite and add the optimized script src to the document.
So compatibility with Font-Awesome is definitely there without any major problems. It’s just not documented anywhere how to use it with astro.
I’d love to see my example being incorporated (in some form or another) in the docs or even having the FortAwesome team consider creating an official astro component.
Found this issue after looking into the same problem for myself. Looks like you can do something like this for SSR:
---
import { icon } from '@fortawesome/fontawesome-svg-core';
import { faHouse } from '@fortawesome/free-solid-svg-icons';
const devIcon = icon(faHouse).html;
---
<div set:html={devIcon}></div>
However, you will have to go and set the width and height for the SVG. I'm doing that like this:
.svg-inline--fa {
width: 1.33em;
height: 1.33em;
}
I got a similar setup to @h93xV2 's working with this, but I'm using Shoelace and it's not playing nice with it yet.
H93xV2's solution can be wrapped in a component to make it easier to use:
FaIcon.astro
---
import type {IconDefinition} from '@fortawesome/fontawesome-svg-core';
import {icon} from '@fortawesome/fontawesome-svg-core';
interface Props {
icon: IconDefinition
}
const iconHtml = icon(Astro.props.icon).html;
---
<style>
.icon {
display: inline-block;
width: 1em;
height: 1em;
}
</style>
<i class="icon" set:html={iconHtml}></i>
Then, to use it (MDX file here):
import { faUser } from '@fortawesome/free-solid-svg-icons';
import FaIcon from '../../../../components/FaIcon.astro';
<FaIcon icon={faUser} />
Same as @carcigenicate but with Fragment
, imported CSS styles and classes.
---
import { icon, type IconDefinition } from "@fortawesome/fontawesome-svg-core";
import "@fortawesome/fontawesome-svg-core/styles.css";
interface Props {
icon: IconDefinition;
class?: string;
}
const iconHtml = icon(Astro.props.icon, {
classes: Array.from(new Set(Astro.props.class?.split(" "))),
}).html;
---
<Fragment set:html={iconHtml} />
And for layer.
---
import { layer, icon, type IconDefinition } from "@fortawesome/fontawesome-svg-core";
import "@fortawesome/fontawesome-svg-core/styles.css";
interface IconsDefinition {
icon: IconDefinition;
class?: string;
}
interface Props {
icons: IconsDefinition[];
class?: string;
}
const layerHtml = layer((push) => {
for (const iconDefinition of Astro.props.icons) {
push(icon(iconDefinition.icon, {
classes: Array.from(new Set(iconDefinition.class?.split(" "))),
}));
}
}, {
classes: Array.from(new Set(Astro.props.class?.split(" "))),
}).html;
---
<Fragment set:html={layerHtml} />
Is your feature request related to a problem?
Font-Awesome supports the major frontend frameworks such as React, Vue… as well as some Meta Frameworks like Next.js, but using it with Astro is still unsupported / undocumented.
Feature description
Astro is a unique meta framework focused on websites and has its own component architecture alternative to react, vue… (.astro files)
unfortunately, there is currently no official integration although astro is increasingly getting used over other meta frameworks because of its better performance and focus on websites rather than applications.
I’d like to see an official component for astro components so we don’t have to use react or svg-core
Alternatives
Alternative to an official component, we should at least create some documentation using Font-Awesome with Astro Layouts / Pages.
Additional context
I managed to get Font-Awesome working (client side) via
@fortawesome/fontawesome-svg-core
and am working on a pure SSR way by using theicon().html
function provided by svg-core. This function could also possibly be used for creating an astro component, similar to how the react / vue components work.Feature request checklist