vite로 빌드한 웹에 favicon을 적용하고 싶은데, vite 자체 config에는 관련한 설정이 없다. (작성일 기준)
더 알아보니 관련 플러그인을 찾았는데, 이상하게 사용 방법에 관한 포스트나 글이 하나도 없는 것이다. 그래서 내가 포스팅했다.
일단 vite-plugin-favicon
이라는 vite plugin이 필요하다.
공식문서는 여기에서 볼 수 있다.
vite-plugin-favicon
을 설치했다면 vite.config
에서 설정을 해 줄 차례이다.
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { ViteFaviconsPlugin } from "vite-plugin-favicon";
export default defineConfig({
plugins: [
react(),
ViteFaviconsPlugin({
logo: "public/assets/logo.png",
}),
],
base: "/lostark_character_search/",
});
기본적인 사용법은 이거다. ViteFaviconPlugin
에 파라미터를 주지 않고 그냥 호출하면 assets/logo.png
를 자동으로 찾아서 favicon으로 사용한다. 다른 폴더에 아이콘 사진이 있다면 위와 같이 logo
에 아이콘 파일의 경로를 지정해주면 된다.
아마 png와 svg 확장자만 받는 것 같다. ico 파일으로 넣으면 안 된다.
이제 빌드를 하면 이런 html이 나온다.
으악 뭐야 이거
head
에 뭔가 잔뜩 들어있다. 이게 뭔가하면 모든 환경에 대응해서 최적화된 favicon을 싹 다 설정한 것이다.
build된 폴더의 assets 폴더를 열어보면 모든 환경에 1:1로 대응하는 favicon이 잔뜩 들어있다.
근데 이러고 배포하면 favicon을 못 찾는다.
왜냐면 link
태그의 href
속성을 보면 그냥 문자열의 나열만 있기 때문이다. 아이콘 파일 명의 일부이긴 한데, 왜 파일명의 일부분만 href
에 들어있는지 모르겠다.
이 문제를 해결하기 위해서는 faviconsConfig
을 따로 설정해줘야한다.
이 부분에 나와 있다.
faviconsConfig
문서는 여기에 나와 있다.
var favicons = require("favicons"),
source = "test/logo.png", // Source image(s). `string`, `buffer` or array of `string`
configuration = {
path: "/", // Path for overriding default icons path. `string`
appName: null, // Your application's name. `string`
appShortName: null, // Your application's short_name. `string`. Optional. If not set, appName will be used
appDescription: null, // Your application's description. `string`
developerName: null, // Your (or your developer's) name. `string`
developerURL: null, // Your (or your developer's) URL. `string`
dir: "auto", // Primary text direction for name, short_name, and description
lang: "en-US", // Primary language for name and short_name
background: "#fff", // Background colour for flattened icons. `string`
theme_color: "#fff", // Theme color user for example in Android's task switcher. `string`
appleStatusBarStyle: "black-translucent", // Style for Apple status bar: "black-translucent", "default", "black". `string`
display: "standalone", // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string`
orientation: "any", // Default orientation: "any", "natural", "portrait" or "landscape". `string`
scope: "/", // set of URLs that the browser considers within your app
start_url: "/?homescreen=1", // Start URL when launching the application from a device. `string`
preferRelatedApplications: false, // Should the browser prompt the user to install the native companion app. `boolean`
relatedApplications: undefined, // Information about the native companion apps. This will only be used if `preferRelatedApplications` is `true`. `Array<{ id: string, url: string, platform: string }>`
version: "1.0", // Your application's version string. `string`
pixel_art: false, // Keeps pixels "sharp" when scaling up, for pixel art. Only supported in offline mode.
loadManifestWithCredentials: false, // Browsers don't send cookies when fetching a manifest, enable this to fix that. `boolean`
manifestMaskable: false, // Maskable source image(s) for manifest.json. "true" to use default source. More information at https://web.dev/maskable-icon/. `boolean`, `string`, `buffer` or array of `string`
icons: {
// Platform Options:
// - offset - offset in percentage
// - background:
// * false - use default
// * true - force use default, e.g. set background for Android icons
// * color - set background for the specified icons
//
android: true, // Create Android homescreen icon. `boolean` or `{ offset, background }` or an array of sources
appleIcon: true, // Create Apple touch icons. `boolean` or `{ offset, background }` or an array of sources
appleStartup: true, // Create Apple startup images. `boolean` or `{ offset, background }` or an array of sources
favicons: true, // Create regular favicons. `boolean` or `{ offset, background }` or an array of sources
windows: true, // Create Windows 8 tile icons. `boolean` or `{ offset, background }` or an array of sources
yandex: true, // Create Yandex browser icon. `boolean` or `{ offset, background }` or an array of sources
},
shortcuts: [
// Your applications's Shortcuts (see: https://developer.mozilla.org/docs/Web/Manifest/shortcuts)
// Array of shortcut objects:
{
name: "View your Inbox", // The name of the shortcut. `string`
short_name: "inbox", // optionally, falls back to name. `string`
description: "View your inbox messages", // optionally, not used in any implemention yet. `string`
url: "/inbox", // The URL this shortcut should lead to. `string`
icon: "test/inbox_shortcut.png", // source image(s) for that shortcut. `string`, `buffer` or array of `string`
},
],
// more shortcuts objects
},
callback = function (error, response) {
if (error) {
console.log(error.message); // Error description e.g. "An unknown error has occurred"
return;
}
console.log(response.images); // Array of { name: string, contents: <buffer> }
console.log(response.files); // Array of { name: string, contents: <string> }
console.log(response.html); // Array of strings (html elements)
};
favicons(source, configuration, callback);
뭐가 많은데 빌드 파일에서도 아이콘이 나오게 하려면 그냥 맨 위에 있는 path
만 설정해주면 된다.
path
를 어떻게 설정해줘야 하냐면, 빌드 폴더에서 아이콘 파일이 들어있는 폴더를 path로 설정해주면 된다.
나는 빌드 폴더 내에서 assets
폴더에 아이콘 파일이 들어있으니까 assets/
이라고 입력해주면 된다.
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { ViteFaviconsPlugin } from "vite-plugin-favicon";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
ViteFaviconsPlugin({
logo: "public/assets/logo.png",
favicons: {
path: "assets/",
},
}),
],
base: "/lostark_character_search/",
});
그럼 이렇게 아이콘 파일 명도 잘 찾고, favicon도 적용된 모습을 볼 수 있다.
근데 manifest.json
파일을 못 찾고 있다. 왜냐하면 manifest.json
은 assets 폴더 밖에 있기 때문이다.
manifest.json
은 이 웹사이트가 웹 앱으로써 실행될 때 필요한 정보들을 담고 있는 파일이다.
아쉽지만 manifest 관련 파일만 경로를 지정하는 config는 찾을 수가 없었다. 혹시 알고 계신다면 댓글로 알려주시면 감사하겠습니다.
그냥 얘네를 assets 폴더 내로 옮겨주자.
이제 잘 응답받는다.
나는 vite
를 사용하면서 거의 모든 면에서 webpack
보다 쾌적했다. favicon 적용하는 부분만 빼고.
그렇지만 favicon을 다양한 플랫폼에 대응하게끔 해주는 부분은 인상깊었다. 덕분에 잘 모르던 favicon에 대해서 좋은 공부했다.