Using multiple fonts across pages in Next JS - import

I'm used to importing google fonts in css files and then using the font-family property. But I want to utilize the "built-in automatic self-hosting" provided by #next/font.
#next/font includes built-in automatic self-hosting for any font file.
This new font system also allows you to conveniently use all Google Fonts with performance and privacy in mind. CSS and font files are downloaded at build time and self-hosted with the rest of your static assets. No requests are sent to Google by the browser.
So far I can only import and use multiple fonts in index.js. I want to use the same fonts in another page about.js without loading the fonts again.
How can I import multiple fonts from #next/font/google and use them across pages and components?
Is there a way I can attach the fonts to particular classes or selectors?
h1 {
font-family: "Exo 2", sans-serif;
}

We cannot attach #next/font/google fonts to particular classes using font-family because they have different names when imported.
We can reuse fonts by doing this:
Create a separate utils/fonts.js file:
import { Exo_2, Noto_Sans } from "#next/font/google";
export const titleFont = Exo_2({
weight: ["500", "600", "700"],
subsets: ["latin"],
});
export const textFont = Noto_Sans({
weight: ["500", "600", "700"],
subsets: ["latin"],
});
Import the fonts required in pages/index.js:
import { textFont, titleFont } from "../utils/fonts";
Use them with className property:
<main className={styles.main + " " + textFont.className}>
<h1 className={titleFont.className}>Home Page</h1>
<p>Hi this is the home page.</p>
</main>
You can do the same thing with local fonts. Just import them in fonts.js and then export their loader functions.
Using variable names like textFont and titleFont helps in forming a uniform system.
You can use the font with other styling classes by simply adding a space in between like this:
{styles.main + " " + textFont.className}
Read documentation here.

In short, I try this method where i can use multiple fonts on my code and apply css on it also without any problem.
Here is my code :
//app/page.js
import Image from 'next/image'
import { Poppins} from '#next/font/google'
import { Anton} from '#next/font/google'
import styles from './page.module.css'
const poppins = Poppins({ weight: '400', subsets: ['latin'] })
const anton = Anton({ weight: '400', subsets: ['latin'] })
export default function Home() {
return (
<main className={styles.main}>
<div >
<h1 className={styles.heading}><span className={anton.className}> Hello </span></h1>
</div>
<div >
<h2 className={styles.heading}><span className={poppins.className}> Hello </span></h2>
</div>
</main>
)
}
You see i use heading and apply styles on it and after that i can use span in inside the heading tag and apply the fonts that i want to use

Related

Is there a way to "inject" pure CSS into MUI v5

I have a custom spinner that is currently using keyframes like so:
import { keyframes } from "#mui/system";
...
const keyframeSpinner = keyframes`
0%{transform:rotate(0deg);}
100%{transform:rotate(360deg);}
`;
...
<Box
sx={{
animation: `${keyframeSpinner} 1s linear infinite`,
}}
/>
...
I don't want to import #mui/system and I don't want to use styled components.
So, I'm trying to find a solution where I can uses pure css or another solution that I'm unaware of.
You can easily apply in-line CSS styles to components using emotion, which is also used by MUI.
For example, here is the css prop from emotion being used to customize background-color and hover on a div. The code you write in the css prop can be pure CSS.
import { css, jsx } from '#emotion/react'
const color = 'darkgreen'
const customCss = css`
background-color: hotpink
&:hover { color: ${color} }
`
render(
<div css = {customCss}>
This div has a hotpink background.
</div>
)

Can't change size and color of svg file using IonIcon

I have a local svg files I downloaded from ionicons website.
I'm trying to change their font size and color, but nothing works.
I tried with img tag and change in the css file, didn't work.
I tried with IonIcon, which also does not work.
This is what I have right now:
const AppHeader = () => {
return (
<div className="header">
<div className="iconsContainer">
<IonIcon src={searchIcon} size="36px" color="white"></IonIcon>
<IonIcon src={cartIcon} size="36px" color="white"></IonIcon>
</div>
</div>
);
};
I also couldn't find anything about IonIcon in Ionic's website and IonIcon's go to definition in VSCode does not work for some reason.
The svg does display, but I can't change the size and color.
Use it like this
<IonIcon icon={searchIcon} style={{fontSize:32, color: 'white'}}/>
Did you import IonIcon like that:-
import { IonIcon } from "#ionic/react";
If you are trying to use ionic icons you need to import the name as well:-
import { search } from "ionicons/icons";
Example with SVG/Images
<IonIcon src="/assets/icons/searchIcon"/>
Example with ionic icons
<IonIcon icon={search} style={{fontSize:36, color: 'white'}} />

Custom google font (poppins) in Tailwind CSS?

I want to use the Google font called poppins and this is the url of the font https://fonts.googleapis.com/css2?family=Poppins:wght#300&display=swap. Does anyone know hot to do this?
There are three steps to getting a custom font into a tailwindcss project.
Getting the font into the project
Configuring tailwindcss to use the font.
Using custom font-family
1. Getting the font into the project (Reply by: Adam Wathan)
Tailwind doesn't do anything special to auto-import fonts or anything, so you need to import them the same way you would in a regular project, either by adding the Google stylesheet reference to the top of your HTML like this:
<!-- index.html or similar -->
<head>
...
<link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
</head>
...or by importing your fonts with #font-face declarations at the beginning of your CSS file:
/* Example file: styles.css */
/* poppins-regular - latin */
#font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 400;
src: url('../fonts/poppins-v15-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('../fonts/poppins-v15-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/poppins-v15-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/poppins-v15-latin-regular.woff') format('woff'), /* Modern Browsers */
url('../fonts/poppins-v15-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/poppins-v15-latin-regular.svg#Poppins') format('svg'); /* Legacy iOS */
}
Which way? According to this SO answer: mostly prefer link
2. Configuring tailwindcss to use the font - tailwind docs
Customizing Font Families
By default, Tailwind provides three font family utilities: a cross-browser sans-serif stack, a cross-browser serif stack, and a cross-browser monospaced stack. You can change, add, or remove these by editing the theme.fontFamily section of your Tailwind config.
// tailwind.config.js
module.exports = {
theme: {
fontFamily: {
// Note: This is #notapatch and not the docs
// I think what it is trying to say is that if you define
// a custom font here you are also removing the default
// font families sans, serif and mono.
//
- 'sans': ['ui-sans-serif', 'system-ui', ...],
- 'serif': ['ui-serif', 'Georgia', ...],
- 'mono': ['ui-monospace', 'SFMono-Regular', ...],
+ 'display': ['Poppins', ...],
+ 'body': ['"Open Sans"', ...],
}
}
}
// Docs end:
Customizing font-family with extend
The font-family docs don't cover this, but I've seen examples of extending the font-family instead of removing the default fonts sans serif and mono ... this is from a github issue by simonswiss
// tailwind.config.js
const defaultTheme = require('tailwindcss/defaultTheme')
module.exports = {
theme: {
+ extend: {
fontFamily: {
sans: ['Poppins', ...defaultTheme.fontFamily.sans]
}
+ }
}
}
... will add Poppins to the font-sans stack, and preserve the other font families like font-mono, font-serif etc.
3. Using custom Font-Family
Using a custom font-family is a matter of adding "font" to the fontFamily name. In our case, font-display and font-sans.
<h1 class="font-display">Example display font</h1>
<p class="font-sans">Example text in body</p>
Note: Changed font to Poppins throughout answer to give consistency across text.
If you want to directly import and use it from Google fonts,
Then add the <link> in your <head> section of your index.html file.
Then in your tailwind.config.js file
module.exports = {
theme: {
extend: {
fontFamily: {
'poppins': ['Poppins'],
}
}
}
}
By defining your own font within extend will preserve the default theme fonts and add/extend your own font.
Now, you can use your font with the class font-poppins along with font-sans etc
You can add fallback font by adding it to the poppins array in the theme extension.
For more, please refer to the below links,
https://tailwindcss.com/docs/theme
https://tailwindcss.com/docs/font-family#customizing
1. Import font
You can use #import... directive from the Google Font website to import web fonts in your global.css file. Be sure to put the directive at the beginning or it is invalid
#import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
#tailwind base;
#tailwind components;
#tailwind utilities;
2. Use the font
As has mentioned by the other anwsers, you can configure the tailwind.config.js to generate a reusable utilities in your project. Besides, you can also use square bracket notation to generate a class on the fly. Just add font-['Poppins'] to class properties.
Here is tailwind playground example:
https://play.tailwindcss.com/xZpx31j8W0
I have this configuration in a .css file
#font-face {
font-display: swap;
font-family: 'Nunito';
font-style: normal;
font-weight: 400;
src: local('Nunito Regular'), local('Nunito-Regular'),
url('~assets/fonts/Nunito-400-cyrillic-ext1.woff2') format('woff2');
}
And this in my tailwind.config.js file
fontFamily: {
// https://tailwindcss.com/docs/font-family#customizing
sans: [
'Nunito'
],
},
Thus I can use it in my markup with
<p class="font-sans">
I'm a sans-serif paragraph.
</p>
So yeah, my font is local but maybe my configuration can give you some insight on how to setup it on your side too.
Then, you could font-face's url key to set in the google fonts url as shown here: https://css-tricks.com/dont-just-copy-the-font-face-out-of-google-fonts-urls/
Here's what I did
In your main scss file
#import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
then in tailwind config....
theme: {
extend: {
fontFamily: {
sans: ['Poppins', ...defaultTheme.fontFamily.sans],
},

FOUC when using #material-ui/core with NextJS/React

My simple NextJS page looks like this (results can be viewed at https://www.schandillia.com/):
/* eslint-disable no-unused-vars */
import React, { PureComponent, Fragment } from 'react';
import Head from 'next/head';
import compose from 'recompose/compose';
import Layout from '../components/Layout';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const styles = {
root: {
textAlign: 'center',
paddingTop: 200,
},
p: {
textTransform: 'uppercase',
color: 'red',
},
};
class Index extends PureComponent {
render() {
const { classes } = this.props;
const title = 'Project Proost';
const description = 'This is the description for the homepage';
return (
<Fragment>
<Head>
<title>{ title }</title>
<meta name="description" content={description} key="description" />
</Head>
<Layout>
<p className={classes.p}>amit</p>
<Button variant="contained" color="secondary">
Secondary
</Button>
</Layout>
</Fragment>
);
}
}
export default withStyles(styles)(Index);
I am importing a bunch of components off the #material-ui/core library to style my items. I also have a local style definition assigned to a style constant.
What seems to be happening here is that my style isn't getting rendered on the server which is why the files being served upon load are sans-style. And then the CSS gets rendered by the client-side code. As a result, there's a flash of unstyled content that lasts almost a second, long enough to be noticable.
Any way to fix this? The entire codebase is up for reference at https://github.com/amitschandillia/proost/tree/master/web.
I ran a similar problem when tried to make a production build of my app, that uses material-ui. I manage to solve by adding a JSS Provider like this:
import JssProvider from "react-jss/lib/JssProvider";
class App extends Component {
render() {
<JssProvider>
*the rest of your material-ui components*
</JssProvider>
}
}
Here's the solution - https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js .
Basically, all you need to do is to sync server-side class names with client-side. The link above shows what you need to do to fix that issue.

How do I globally override variant, color, style, etc. for Material-UI components?

Instead of doing this everywhere:
<Button variant="contained" color="primary"
style={{textTransform: "none"}}
>
Description
</Button>
I just want to write:
<Button>
Description
</Button>
Can I use theme overrides to do this and what would that look like?
Note that I'm trying to override both Material-UI properties and CSS styles. I want to do this globally (i.e. not using withStyles() stuff everywhere).
Or can this only be done by defining some kind of new AppButton component?
Currently using material-ui 3.2.2
You can do this with global overrides for your theme.
Documentation is here https://material-ui.com/customization/themes/#customizing-all-instances-of-a-component-type
Doing it this way will still allow you override the variant on a per component basis as well.
const theme = createMuiTheme({
props: {
// Name of the component ⚛️
MuiButton: {
// The properties to apply
variant: 'contained'
},
},
});
Here's an alternate way to do this, without defining a new component.
Custom components can be awkward when used with Material-UI's JSS styling solution with Typescript. I've found it difficult to define WithStyle types when combining style types from the shared component and the thing using it.
Instead of defining components, it's possible to define sets of default properties that you then apply with the spread operator.
Define and export a standard set of shared props somewhere out in your app:
import {LinearProgressProps} from "#material-ui/core/LinearProgress";
export const linearProps: LinearProgressProps = {
variant:"indeterminate",
color:"primary",
style:{height:"2px"},
};
Then use those props in your app:
<LinearProgress {...linearProps} />
This is then easy to override with custom properties, custom inline styles or JSS generated styles:
<LinearProgress {...linearProps} className={classes.customProgress}
color="secondary" style={{...linearProps.style, width: "100%"}} />
For anyone finding this question, assuming there is no Material-UI way to do this, here's my custom button component.
import * as React from "react";
import {Button} from "#material-ui/core";
import {ButtonProps} from "#material-ui/core/Button";
export class AppButton extends React.Component<ButtonProps, {}>{
render(){
let {style, ...props} = this.props;
return <Button {...props} variant="contained" color="primary"
style={{...style, textTransform: "none"}}
>
{this.props.children}
</Button>
}
}
AppButton.muiName = 'Button';