@exabytellc/utils
Version:
EB react utils to make everything a little easier!
143 lines (131 loc) • 6.09 kB
JavaScript
import path from "path";
/**
* Vite Plugin: Insert Meta Tags into HTML
*
* This plugin dynamically injects meta tags and other relevant metadata into the `<head>` of your `index.html`.
* Useful for setting SEO metadata, social media tags, icons, and more.
*
* @param {Object} options - Plugin options?.
* @param {string} [options?.charset="UTF-8"] - Character encoding of the document.
* @param {string} [options?.viewport="width=device-width, initial-scale=1.0"] - Viewport settings for responsiveness.
* @param {boolean} [options?.compatibleIE=true] - Enables Internet Explorer compatibility mode.
*
* @param {string} [options?.title="My Website"] - The website title.
* @param {string} [options?.description="This is my awesome website."] - A brief description of the website.
* @param {string} [options?.keywords="web, vite, seo"] - Keywords for search engine optimization.
* @param {string} [options?.author="Exabyte LLC"] - The author's name.
* @param {string} [options?.company="Exabyte LLC"] - The company name.
* @param {string} [options?.themeColor="#ffffff"] - The theme color in HEX format.
*
* @param {string} [options?.favicon="favicon.png"] - Path to the favicon.
* @param {string|null} [options?.appleTouchIcon=null] - Path to the Apple Touch Icon.
* @param {Array} [options?.icons=[]] - Additional icons for different devices.
*
* @param {string|null} [options?.socialImage=null] - Image URL for social media previews.
* @param {string|null} [options?.socialUrl=null] - Canonical URL for social media.
* @param {string|null} [options?.twitterImage=null] - Image URL for Twitter preview.
* @param {string|null} [options?.twitterSummary=null] - Twitter card summary type.
*
* @param {string|null} [options?.appleMobileWebAppTitle=null] - iOS web app title.
* @param {string|null} [options?.appleMobileWebAppStatusBarStyle=null] - Status bar style for iOS web apps.
*
* @param {string|null} [options?.manifestPath=null] - Path to the Web App Manifest file.
*
* @param {string} [options?.robots="index, follow"] - Robots meta tag content for SEO control.
*
* @param {string|null} [options?.androidAppPackage=null] - Android package name for deep linking.
* @param {string|null} [options?.androidAppURL=null] - Android deep link URL.
* @param {string|null} [options?.iosAppID=null] - iOS App Store ID.
* @param {string|null} [options?.iosAppURL=null] - iOS deep link URL.
*
* @returns {Object} - Vite plugin configuration.
*/
export default function insertHtmlMetaPlugin(options = {}) {
return {
name: "vite-insert-html-meta-plugin",
transformIndexHtml(html) {
return html.replace("<head>", `<head>\n${generateMetaTags()}`);
},
};
/**
* Generates the necessary meta tags based on the provided options?.
* @returns {string} - Generated meta tags as a string.
*/
function generateMetaTags() {
let meta = "";
// Basic meta tags
if (options?.charset) meta += `\t<meta charset="${options?.charset}" />\n`;
if (options?.viewport)
meta += `\t<meta name="viewport" content="${options?.viewport}" />\n`;
if (options?.compatibleIE)
meta += `\t<meta http-equiv="X-UA-Compatible" content="IE=edge" />\n`;
// Basic Info
if (options?.title) meta += `\t<title>${options?.title}</title>\n`;
if (options?.description)
meta += `\t<meta name="description" content="${options?.description}" />\n`;
if (options?.keywords)
meta += `\t<meta name="keywords" content="${options?.keywords}" />\n`;
if (options?.author)
meta += `\t<meta name="author" content="${options?.author}" />\n`;
if (options?.company)
meta += `\t<meta name="copyright" content="${options?.company}" />\n`;
if (options?.themeColor)
meta += `\t<meta name="theme-color" content="${options?.themeColor}" />\n`;
// Icons
if (options?.favicon)
meta += `\t<link rel="icon" href="${
options?.favicon
}" type="${getFileType(options?.favicon)}" />\n`;
if (options?.appleTouchIcon)
meta += `\t<link rel="apple-touch-icon" href="${options?.appleTouchIcon}" />\n`;
options?.icons?.forEach(({ src, sizes, type }) => {
meta += `\t<link rel="icon" href="${src}" sizes="${sizes}" type="${
type ?? getFileType(src)
}" />\n`;
});
// Open Graph & Twitter Meta Tags
if (options?.socialImage)
meta += `\t<meta property="og:image" content="${options?.socialImage}" />\n`;
if (options?.socialUrl)
meta += `\t<meta property="og:url" content="${options?.socialUrl}" />\n`;
if (options?.twitterImage)
meta += `\t<meta name="twitter:image" content="${options?.twitterImage}" />\n`;
if (options?.twitterSummary)
meta += `\t<meta name="twitter:card" content="${options?.twitterSummary}" />\n`;
// Web App Manifest
if (options?.manifestPath)
meta += `\t<link rel="manifest" href="${options?.manifestPath}" />\n`;
// Robots.txt
if (options?.robots)
meta += `\t<meta name="robots" content="${options?.robots}" />\n`;
return meta;
}
/**
* Determines the MIME type of an icon file based on its extension.
* @param {string} filePath - Path to the icon file.
* @returns {string} - MIME type.
*/
function getFileType(filePath) {
const ext = path.extname(filePath).toLowerCase();
const typeMap = {
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".ico": "image/x-icon",
".svg": "image/svg+xml",
};
return typeMap[ext] || "image/png"; // Default to PNG if unknown
}
}
/**
* Creates an object representing an icon for meta tags.
*
* @param {string} src - Path to the icon.
* @param {string} sizes - Icon sizes (e.g., "64x64").
* @param {string} [type] - MIME type of the icon.
* @returns {Object} - Icon object.
*/
export function htmlMetaIcon(src, sizes, type) {
return { src, sizes, type };
}