Socket
Socket
Sign inDemoInstall

@next/font

Package Overview
Dependencies
Maintainers
5
Versions
1033
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@next/font - npm Package Compare versions

Comparing version 13.1.1 to 13.4.4

dist/constants.d.ts

4

dist/google/loader.d.ts
import type { FontLoader } from 'next/font';
declare const downloadGoogleFonts: FontLoader;
export default downloadGoogleFonts;
declare const nextFontGoogleFontLoader: FontLoader;
export default nextFontGoogleFontLoader;

@@ -25,14 +25,13 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
const font_utils_1 = require("next/dist/server/font-utils");
// @ts-ignore
const Log = __importStar(require("next/dist/build/output/log"));
// @ts-ignore
const chalk_1 = __importDefault(require("next/dist/compiled/chalk"));
const utils_1 = require("./utils");
const utils_2 = require("../utils");
const validate_google_font_function_call_1 = require("./validate-google-font-function-call");
const get_font_axes_1 = require("./get-font-axes");
const get_google_fonts_url_1 = require("./get-google-fonts-url");
const next_font_error_1 = require("../next-font-error");
const find_font_files_in_css_1 = require("./find-font-files-in-css");
const get_fallback_font_override_metrics_1 = require("./get-fallback-font-override-metrics");
const fetch_css_from_google_fonts_1 = require("./fetch-css-from-google-fonts");
const fetch_font_file_1 = require("./fetch-font-file");
const cssCache = new Map();

@@ -50,28 +49,11 @@ const fontCache = new Map();

}
const downloadGoogleFonts = async ({ functionName, data, config, emitFontFile, isDev, isServer, loaderContext, }) => {
var _a, _b, _c;
const subsets = (config === null || config === void 0 ? void 0 : config.subsets) || [];
const { fontFamily, weights, styles, display, preload, selectedVariableAxes, fallback, adjustFontFallback, variable, subsets: callSubsets, } = (0, utils_1.validateData)(functionName, data);
if (isServer && preload && !callSubsets && !(config === null || config === void 0 ? void 0 : config.subsets)) {
Log.warn(`The ${chalk_1.default.bold('@next/font/google')} font ${chalk_1.default.bold(fontFamily)} has no selected subsets. Please specify subsets in the function call or in your ${chalk_1.default.bold('next.config.js')}, otherwise no fonts will be preloaded. Read more: https://nextjs.org/docs/messages/google-fonts-missing-subsets`);
}
const fontAxes = (0, utils_1.getFontAxes)(fontFamily, weights, styles, selectedVariableAxes);
const url = (0, utils_1.getUrl)(fontFamily, fontAxes, display);
// Find fallback font metrics
let adjustFontFallbackMetrics;
if (adjustFontFallback) {
try {
const { ascent, descent, lineGap, fallbackFont, sizeAdjust } = (0, font_utils_1.calculateSizeAdjustValues)(require('next/dist/server/google-font-metrics.json')[fontFamily]);
adjustFontFallbackMetrics = {
fallbackFont,
ascentOverride: `${ascent}%`,
descentOverride: `${descent}%`,
lineGapOverride: `${lineGap}%`,
sizeAdjust: `${sizeAdjust}%`,
};
}
catch {
Log.error(`Failed to find font override values for font \`${fontFamily}\``);
}
}
const nextFontGoogleFontLoader = async ({ functionName, data, emitFontFile, isDev, isServer, }) => {
var _a;
const { fontFamily, weights, styles, display, preload, selectedVariableAxes, fallback, adjustFontFallback, variable, subsets, } = (0, validate_google_font_function_call_1.validateGoogleFontFunctionCall)(functionName, data[0]);
// Validate and get the font axes required to generated the URL
const fontAxes = (0, get_font_axes_1.getFontAxes)(fontFamily, weights, styles, selectedVariableAxes);
// Generate the Google Fonts URL from the font family, axes and display value
const url = (0, get_google_fonts_url_1.getGoogleFontsUrl)(fontFamily, fontAxes, display);
// Get precalculated fallback font metrics, used to generate the fallback font CSS
const adjustFontFallbackMetrics = adjustFontFallback ? (0, get_fallback_font_override_metrics_1.getFallbackFontOverrideMetrics)(fontFamily) : undefined;
const result = {

@@ -87,8 +69,17 @@ fallbackFonts: fallback,

try {
/**
* Hacky way to make sure the fetch is only done once.
* Otherwise both the client and server compiler would fetch the CSS.
* The reason we need to return the actual CSS from both the server and client is because a hash is generated based on the CSS content.
*/
const hasCachedCSS = cssCache.has(url);
// Fetch CSS from Google Fonts or get it from the cache
let fontFaceDeclarations = hasCachedCSS
? cssCache.get(url)
: await (0, utils_1.fetchCSSFromGoogleFonts)(url, fontFamily).catch(() => null);
: await (0, fetch_css_from_google_fonts_1.fetchCSSFromGoogleFonts)(url, fontFamily, isDev).catch((err) => {
console.error(err);
return null;
});
if (!hasCachedCSS) {
cssCache.set(url, fontFaceDeclarations);
cssCache.set(url, fontFaceDeclarations !== null && fontFaceDeclarations !== void 0 ? fontFaceDeclarations : null);
}

@@ -98,35 +89,21 @@ else {

}
if (fontFaceDeclarations === null) {
(0, utils_2.nextFontError)(`Failed to fetch \`${fontFamily}\` from Google Fonts.`);
if (fontFaceDeclarations == null) {
(0, next_font_error_1.nextFontError)(`Failed to fetch \`${fontFamily}\` from Google Fonts.`);
}
// CSS Variables may be set on a body tag, ignore them to keep the CSS module pure
fontFaceDeclarations = fontFaceDeclarations.split('body {')[0];
// Find font files to download
const fontFiles = [];
let currentSubset = '';
for (const line of fontFaceDeclarations.split('\n')) {
// Each @font-face has the subset above it in a comment
const newSubset = (_a = /\/\* (.+?) \*\//.exec(line)) === null || _a === void 0 ? void 0 : _a[1];
if (newSubset) {
currentSubset = newSubset;
}
else {
const googleFontFileUrl = (_b = /src: url\((.+?)\)/.exec(line)) === null || _b === void 0 ? void 0 : _b[1];
if (googleFontFileUrl &&
!fontFiles.some((foundFile) => foundFile.googleFontFileUrl === googleFontFileUrl)) {
fontFiles.push({
googleFontFileUrl,
preloadFontFile: !!preload && (callSubsets !== null && callSubsets !== void 0 ? callSubsets : subsets).includes(currentSubset),
});
}
}
}
// Download font files
// Find font files to download, provide the array of subsets we want to preload if preloading is enabled
const fontFiles = (0, find_font_files_in_css_1.findFontFilesInCss)(fontFaceDeclarations, preload ? subsets : undefined);
// Download the font files extracted from the CSS
const downloadedFiles = await Promise.all(fontFiles.map(async ({ googleFontFileUrl, preloadFontFile }) => {
const hasCachedFont = fontCache.has(googleFontFileUrl);
// Download the font file or get it from cache
const fontFileBuffer = hasCachedFont
? fontCache.get(googleFontFileUrl)
: await (0, utils_1.fetchFontFile)(googleFontFileUrl).catch(() => null);
: await (0, fetch_font_file_1.fetchFontFile)(googleFontFileUrl, isDev).catch((err) => {
console.error(err);
return null;
});
if (!hasCachedFont) {
fontCache.set(googleFontFileUrl, fontFileBuffer);
fontCache.set(googleFontFileUrl, fontFileBuffer !== null && fontFileBuffer !== void 0 ? fontFileBuffer : null);
}

@@ -136,8 +113,8 @@ else {

}
if (fontFileBuffer === null) {
(0, utils_2.nextFontError)(`Failed to fetch \`${fontFamily}\` from Google Fonts.`);
if (fontFileBuffer == null) {
(0, next_font_error_1.nextFontError)(`Failed to fetch \`${fontFamily}\` from Google Fonts.`);
}
const ext = /\.(woff|woff2|eot|ttf|otf)$/.exec(googleFontFileUrl)[1];
// Emit font file to .next/static/media
const selfHostedFileUrl = emitFontFile(fontFileBuffer, ext, preloadFontFile);
const selfHostedFileUrl = emitFontFile(fontFileBuffer, ext, preloadFontFile, !!adjustFontFallbackMetrics);
return {

@@ -148,3 +125,11 @@ googleFontFileUrl,

}));
// Replace @font-face sources with self-hosted files
/**
* Replace the @font-face sources with the self-hosted files we just downloaded to .next/static/media
*
* E.g.
* @font-face {
* font-family: 'Inter';
* src: url(https://fonts.gstatic.com/...) -> url(/_next/static/media/_.woff2)
* }
*/
let updatedCssResponse = fontFaceDeclarations;

@@ -160,3 +145,2 @@ for (const { googleFontFileUrl, selfHostedFileUrl } of downloadedFiles) {

catch (err) {
loaderContext.cacheable(false);
if (isDev) {

@@ -169,3 +153,3 @@ if (isServer) {

font-family: '${fontFamily} Fallback';
src: local("${(_c = adjustFontFallbackMetrics === null || adjustFontFallbackMetrics === void 0 ? void 0 : adjustFontFallbackMetrics.fallbackFont) !== null && _c !== void 0 ? _c : 'Arial'}");`;
src: local("${(_a = adjustFontFallbackMetrics === null || adjustFontFallbackMetrics === void 0 ? void 0 : adjustFontFallbackMetrics.fallbackFont) !== null && _a !== void 0 ? _a : 'Arial'}");`;
if (adjustFontFallbackMetrics) {

@@ -189,2 +173,2 @@ css += `

};
exports.default = downloadGoogleFonts;
exports.default = nextFontGoogleFontLoader;
import type { FontLoader } from 'next/font';
declare const fetchFonts: FontLoader;
export default fetchFonts;
declare const nextFontLocalFontLoader: FontLoader;
export default nextFontLocalFontLoader;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
// eslint-disable-next-line import/no-extraneous-dependencies
const fontkit_1 = __importDefault(require("@next/font/dist/fontkit"));
let fontFromBuffer;
try {
const mod = require('../fontkit').default;
fontFromBuffer = mod.default || mod;
}
catch { }
const util_1 = require("util");
const utils_1 = require("./utils");
const utils_2 = require("../utils");
const NORMAL_WEIGHT = 400;
const BOLD_WEIGHT = 700;
function getWeightNumber(weight) {
// Weight can be 'normal', 'bold' or a number https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-weight
return weight === 'normal'
? NORMAL_WEIGHT
: weight === 'bold'
? BOLD_WEIGHT
: Number(weight);
}
function getDistanceFromNormalWeight(weight) {
if (!weight)
return 0;
const [firstWeight, secondWeight] = weight
.trim()
.split(/ +/)
.map(getWeightNumber);
if (Number.isNaN(firstWeight) || Number.isNaN(secondWeight)) {
(0, utils_2.nextFontError)(`Invalid weight value in src array: \`${weight}\`.\nExpected \`normal\`, \`bold\` or a number.`);
}
// Not a variable font
if (!secondWeight) {
return firstWeight - NORMAL_WEIGHT;
}
// Normal weight is within variable font range
if (firstWeight <= NORMAL_WEIGHT && secondWeight >= NORMAL_WEIGHT) {
return 0;
}
// Return the distance of normal weight to the variable font range
const firstWeightDistance = firstWeight - NORMAL_WEIGHT;
const secondWeightDistance = secondWeight - NORMAL_WEIGHT;
if (Math.abs(firstWeightDistance) < Math.abs(secondWeightDistance)) {
return firstWeightDistance;
}
return secondWeightDistance;
}
const fetchFonts = async ({ functionName, variableName, data, emitFontFile, resolve, loaderContext, }) => {
const { src, display, fallback, preload, variable, adjustFontFallback, declarations, weight: defaultWeight, style: defaultStyle, } = (0, utils_1.validateData)(functionName, data[0]);
const pick_font_file_for_fallback_generation_1 = require("./pick-font-file-for-fallback-generation");
const get_fallback_metrics_from_font_file_1 = require("./get-fallback-metrics-from-font-file");
const validate_local_font_function_call_1 = require("./validate-local-font-function-call");
const nextFontLocalFontLoader = async ({ functionName, variableName, data, emitFontFile, resolve, loaderContext, }) => {
const { src, display, fallback, preload, variable, adjustFontFallback, declarations, weight: defaultWeight, style: defaultStyle, } = (0, validate_local_font_function_call_1.validateLocalFontFunctionCall)(functionName, data[0]);
// Load all font files and emit them to the .next output directory
// Also generate a @font-face CSS for each font file
const fontFiles = await Promise.all(src.map(async ({ path, style, weight, ext, format }) => {
const resolved = await resolve(path);
const fileBuffer = await (0, util_1.promisify)(loaderContext.fs.readFile)(resolved);
const fontUrl = emitFontFile(fileBuffer, ext, preload);
const fontUrl = emitFontFile(fileBuffer, ext, preload, typeof adjustFontFallback === 'undefined' || !!adjustFontFallback);
// Try to load font metadata from the font file using fontkit.
// The data is used to calculate the fallback font override values.
let fontMetadata;
try {
fontMetadata = (0, fontkit_1.default)(fileBuffer);
fontMetadata = fontFromBuffer === null || fontFromBuffer === void 0 ? void 0 : fontFromBuffer(fileBuffer);
}

@@ -61,2 +32,3 @@ catch (e) {

}
// Get all values that should be added to the @font-face declaration
const fontFaceProperties = [

@@ -76,8 +48,8 @@ ...(declarations

];
// Generate the @font-face CSS from the font-face properties
const css = `@font-face {\n${fontFaceProperties
.map(([property, value]) => `${property}: ${value};`)
.join('\n')}\n}\n`;
return {
css: `@font-face {
${fontFaceProperties
.map(([property, value]) => `${property}: ${value};`)
.join('\n')}
}\n`,
css,
fontMetadata,

@@ -88,32 +60,8 @@ weight,

}));
// Add fallback font
// Calculate the fallback font override values using the font file metadata
let adjustFontFallbackMetrics;
if (adjustFontFallback !== false) {
// Pick the font file to generate a fallback font from.
// Prefer the file closest to normal weight, this will typically make up most of the text on a page.
const fallbackFontFile = fontFiles.reduce((usedFontFile, currentFontFile) => {
if (!usedFontFile)
return currentFontFile;
const usedFontDistance = getDistanceFromNormalWeight(usedFontFile.weight);
const currentFontDistance = getDistanceFromNormalWeight(currentFontFile.weight);
// Prefer normal style if they have the same weight
if (usedFontDistance === currentFontDistance &&
(typeof currentFontFile.style === 'undefined' ||
currentFontFile.style === 'normal')) {
return currentFontFile;
}
const absUsedDistance = Math.abs(usedFontDistance);
const absCurrentDistance = Math.abs(currentFontDistance);
// Use closest absolute distance to normal weight
if (absCurrentDistance < absUsedDistance)
return currentFontFile;
// Prefer the thinner font if both are the same absolute distance from normal weight
if (absUsedDistance === absCurrentDistance &&
currentFontDistance < usedFontDistance) {
return currentFontFile;
}
return usedFontFile;
});
const fallbackFontFile = (0, pick_font_file_for_fallback_generation_1.pickFontFileForFallbackGeneration)(fontFiles);
if (fallbackFontFile.fontMetadata) {
adjustFontFallbackMetrics = (0, utils_2.calculateFallbackFontValues)(fallbackFontFile.fontMetadata, adjustFontFallback === 'Times New Roman' ? 'serif' : 'sans-serif');
adjustFontFallbackMetrics = (0, get_fallback_metrics_from_font_file_1.getFallbackMetricsFromFontFile)(fallbackFontFile.fontMetadata, adjustFontFallback === 'Times New Roman' ? 'serif' : 'sans-serif');
}

@@ -130,2 +78,2 @@ }

};
exports.default = fetchFonts;
exports.default = nextFontLocalFontLoader;
{
"name": "@next/font",
"version": "13.1.1",
"version": "13.4.4",
"repository": {

@@ -8,2 +8,3 @@ "url": "vercel/next.js",

},
"types": "dist/types.d.ts",
"files": [

@@ -16,3 +17,3 @@ "dist",

"scripts": {
"build": "rimraf dist && pnpm ncc-fontkit && tsc -d -p tsconfig.json",
"build": "node ../../scripts/rm.mjs dist && pnpm ncc-fontkit && tsc -d -p tsconfig.json",
"prepublishOnly": "cd ../../ && turbo run build",

@@ -19,0 +20,0 @@ "dev": "pnpm ncc-fontkit && tsc -d -w -p tsconfig.json",

@@ -7,2 +7,2 @@ # `@next/font`

[Read more](https://beta.nextjs.org/docs/optimizing/fonts)
[Read more](https://nextjs.org/docs/app/building-your-application/optimizing/fonts)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc