new favicon script
4
.gitignore
vendored
@ -37,4 +37,6 @@ yarn-error.log*
|
|||||||
.swc
|
.swc
|
||||||
coverage
|
coverage
|
||||||
public/matomo.js
|
public/matomo.js
|
||||||
public/favicon/
|
# public/favicon*
|
||||||
|
# public/apple-touch-icon*
|
||||||
|
# public/manifest*
|
55
README.md
@ -25,10 +25,12 @@
|
|||||||
- [📇 Client-side vCard creation](#-client-side-vcard-creation)
|
- [📇 Client-side vCard creation](#-client-side-vcard-creation)
|
||||||
- [💎 Importing SVG assets](#-importing-svg-assets)
|
- [💎 Importing SVG assets](#-importing-svg-assets)
|
||||||
- [🍬 Typekit component](#-typekit-component)
|
- [🍬 Typekit component](#-typekit-component)
|
||||||
|
- [🤓 Scripts](#-scripts)
|
||||||
|
- [🎈 Add a new project](#-add-a-new-project)
|
||||||
|
- [🌄 Favicon generation](#-favicon-generation)
|
||||||
- [✨ Development](#-development)
|
- [✨ Development](#-development)
|
||||||
- [🔮 Linting](#-linting)
|
- [🔮 Linting](#-linting)
|
||||||
- [👩🔬 Testing](#-testing)
|
- [👩🔬 Testing](#-testing)
|
||||||
- [🎈 Add a new project](#-add-a-new-project)
|
|
||||||
- [🚚 Deployment](#-deployment)
|
- [🚚 Deployment](#-deployment)
|
||||||
- [🏛 Licenses](#-licenses)
|
- [🏛 Licenses](#-licenses)
|
||||||
|
|
||||||
@ -124,6 +126,38 @@ If you want to know how, have a look at the respective component:
|
|||||||
|
|
||||||
- [`src/components/Typekit/index.tsx`](src/components/Typekit/index.tsx)
|
- [`src/components/Typekit/index.tsx`](src/components/Typekit/index.tsx)
|
||||||
|
|
||||||
|
## 🤓 Scripts
|
||||||
|
|
||||||
|
### 🎈 Add a new project
|
||||||
|
|
||||||
|
To add a new project, run the following command. This adds a new item to the top of the `projects.yml` file, creating the title & slug from the argument:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run new -- "Hello"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then continue modifying the new entry in [`_content/projects.yml`](_content/projects.yml).
|
||||||
|
|
||||||
|
Finally, add as many images as needed with the file name format and put into `public/images/`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SLUG-01.png
|
||||||
|
SLUG-02.png
|
||||||
|
SLUG-03.png
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🌄 Favicon generation
|
||||||
|
|
||||||
|
This generates all required favcion sizes from:
|
||||||
|
|
||||||
|
- `src/images/favicon-512.png`
|
||||||
|
- `src/images/favicon.svg`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run favicon
|
||||||
|
```
|
||||||
|
|
||||||
## ✨ Development
|
## ✨ Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -165,25 +199,6 @@ npm test
|
|||||||
|
|
||||||
Most test files live beside the respective component. Testing setup, fixtures, and mocks can be found in the `tests/` folder.
|
Most test files live beside the respective component. Testing setup, fixtures, and mocks can be found in the `tests/` folder.
|
||||||
|
|
||||||
### 🎈 Add a new project
|
|
||||||
|
|
||||||
To add a new project, run the following command. This adds a new item to the top of the `projects.yml` file, creating the title & slug from the argument:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run new -- "Hello"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then continue modifying the new entry in [`_content/projects.yml`](_content/projects.yml).
|
|
||||||
|
|
||||||
Finally, add as many images as needed with the file name format and put into `public/images/`:
|
|
||||||
|
|
||||||
```text
|
|
||||||
SLUG-01.png
|
|
||||||
SLUG-02.png
|
|
||||||
SLUG-03.png
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚚 Deployment
|
## 🚚 Deployment
|
||||||
|
|
||||||
Every branch or Pull Request is automatically deployed by [Vercel](https://vercel.com) with their GitHub integration, where the `main` branch is automatically aliased to `matthiaskretschmann.com`. A link to a preview deployment will appear under each Pull Request.
|
Every branch or Pull Request is automatically deployed by [Vercel](https://vercel.com) with their GitHub integration, where the `main` branch is automatically aliased to `matthiaskretschmann.com`. A link to a preview deployment will appear under each Pull Request.
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"available": "👔 Available for new projects. <a href=\"mailto:m@kretschmann.io\">Let’s talk</a>!",
|
"available": "👔 Available for new projects. <a href=\"mailto:m@kretschmann.io\">Let’s talk</a>!",
|
||||||
"unavailable": "Not available for new projects."
|
"unavailable": "Not available for new projects."
|
||||||
},
|
},
|
||||||
"gpg": "https://kretschmann.io/pub.gpg",
|
"gpg": "/gpg.txt",
|
||||||
"addressbook": "/matthias-kretschmann.vcf",
|
"addressbook": "/matthias-kretschmann.vcf",
|
||||||
"bugs": "https://github.com/kremalicious/portfolio/issues/new",
|
"bugs": "https://github.com/kremalicious/portfolio/issues/new",
|
||||||
"matomoUrl": "https://analytics.kremalicious.com",
|
"matomoUrl": "https://analytics.kremalicious.com",
|
||||||
|
@ -23,7 +23,9 @@ const next = (phase, { defaultConfig }) => {
|
|||||||
return typeof defaultConfig.webpack === 'function'
|
return typeof defaultConfig.webpack === 'function'
|
||||||
? defaultConfig.webpack(config, options)
|
? defaultConfig.webpack(config, options)
|
||||||
: config
|
: config
|
||||||
}
|
},
|
||||||
|
// https://nextjs.org/docs/api-reference/next.config.js/react-strict-mode
|
||||||
|
reactStrictMode: true
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextConfig
|
return nextConfig
|
||||||
|
57
package-lock.json
generated
@ -42,6 +42,7 @@
|
|||||||
"prepend": "^1.0.2",
|
"prepend": "^1.0.2",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"sharp": "^0.31.2",
|
"sharp": "^0.31.2",
|
||||||
|
"sharp-ico": "^0.1.5",
|
||||||
"slugify": "^1.6.5",
|
"slugify": "^1.6.5",
|
||||||
"stylelint": "^14.14.1",
|
"stylelint": "^14.14.1",
|
||||||
"stylelint-config-prettier": "^9.0.4",
|
"stylelint-config-prettier": "^9.0.4",
|
||||||
@ -1933,6 +1934,12 @@
|
|||||||
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
|
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@canvas/image-data": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@cspotcode/source-map-support": {
|
"node_modules/@cspotcode/source-map-support": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
@ -5008,6 +5015,33 @@
|
|||||||
"integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==",
|
"integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/decode-bmp": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz",
|
||||||
|
"integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@canvas/image-data": "^1.0.0",
|
||||||
|
"to-data-view": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/decode-ico": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@canvas/image-data": "^1.0.0",
|
||||||
|
"decode-bmp": "^0.2.0",
|
||||||
|
"to-data-view": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/decode-named-character-reference": {
|
"node_modules/decode-named-character-reference": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
|
||||||
@ -6797,6 +6831,12 @@
|
|||||||
"node": ">=10.17.0"
|
"node": ">=10.17.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ico-endec": {
|
||||||
|
"version": "0.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz",
|
||||||
|
"integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
@ -11406,6 +11446,17 @@
|
|||||||
"url": "https://opencollective.com/libvips"
|
"url": "https://opencollective.com/libvips"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sharp-ico": {
|
||||||
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/sharp-ico/-/sharp-ico-0.1.5.tgz",
|
||||||
|
"integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"decode-ico": "*",
|
||||||
|
"ico-endec": "*",
|
||||||
|
"sharp": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sharp/node_modules/semver": {
|
"node_modules/sharp/node_modules/semver": {
|
||||||
"version": "7.3.8",
|
"version": "7.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
@ -12202,6 +12253,12 @@
|
|||||||
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
|
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/to-data-view": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/to-fast-properties": {
|
"node_modules/to-fast-properties": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
"author": "Matthias Kretschmann <m@kretschmann.io>",
|
"author": "Matthias Kretschmann <m@kretschmann.io>",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm run pregenerate && next",
|
"start": "next",
|
||||||
"build": "npm run pregenerate && next build",
|
"build": "next build",
|
||||||
"preview": "npm run build && next start",
|
"preview": "npm run build && next start",
|
||||||
"export": "npm run pregenerate && next export",
|
"export": "next export",
|
||||||
"typecheck": "tsc",
|
"typecheck": "tsc",
|
||||||
"lint:js": "next lint",
|
"lint:js": "next lint",
|
||||||
"lint:css": "stylelint ./src/**/*.css",
|
"lint:css": "stylelint ./src/**/*.css",
|
||||||
@ -21,8 +21,7 @@
|
|||||||
"test": "NODE_ENV=test npm run lint && npm run typecheck && npm run jest",
|
"test": "NODE_ENV=test npm run lint && npm run typecheck && npm run jest",
|
||||||
"deploy:s3": "./scripts/deploy-s3.sh",
|
"deploy:s3": "./scripts/deploy-s3.sh",
|
||||||
"new": "ts-node-esm ./scripts/new.ts",
|
"new": "ts-node-esm ./scripts/new.ts",
|
||||||
"favicon": "ts-node-esm ./scripts/favicon.ts",
|
"favicon": "ts-node-esm ./scripts/favicon.ts"
|
||||||
"pregenerate": "npm run favicon"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@giphy/js-fetch-api": "^4.4.0",
|
"@giphy/js-fetch-api": "^4.4.0",
|
||||||
|
BIN
public/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 2.0 KiB |
27
public/favicon.svg
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
>
|
||||||
|
<style>
|
||||||
|
#background {
|
||||||
|
fill: #e7eef4;
|
||||||
|
}
|
||||||
|
#logomark {
|
||||||
|
fill: #6b7f88;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
#background {
|
||||||
|
fill: #161a1b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="background" width="512" height="512" />
|
||||||
|
<path
|
||||||
|
id="logomark"
|
||||||
|
d="M397,91 L421,115 L114,421 L91,398 L397,91 Z M397,182 L421,206 L205,421 L182,398 L397,182 Z M307,91 L330,115 L114,330 L91,307 L307,91 Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 593 B |
185
public/gpg.txt
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
M3UJphzlZ3GP7/sbqmfNqmcRQKqpuR1OkOtdQbnuvZueraecPDn7kaVTH6/aDiqd
|
||||||
|
PRulwGf8vAYz2DLX8r507lgSHBEqCUw7wzXI/uPbFsfGNu9eDhskuHHQvsi3j4s3
|
||||||
|
XD2RjpcNduSyZC36ZCX4UgUhHX9/wFKb+xdOLke2tDy6/K5mr55OBeYWEOlIXMFS
|
||||||
|
EeGJhZ2ySI9EYrPpRcaEx7qOjznaujxaGjkCrTTTPz/bQmYwbw/bw90+w9hSh+Km
|
||||||
|
/AUA9CvOjAvKVilZ00xqzpg35wS6czFN3PdPojp91fMNUIbonELk/qyS59Er/b9Y
|
||||||
|
xW+3Mb9p35q6d4jvvtlZLWc/y2OOGgptdQ/OEJhU5zaV8RVNCKnCPbQoTWF0dGhp
|
||||||
|
YXMgS3JldHNjaG1hbm4gPGtyZW1hQGpwYmVybGluLmRlPokCVAQTAQoAPgIbAwUL
|
||||||
|
CQgHAwUVCgkICwUWAgMBAAIeAQIXgBYhBJrA95Du12SgGDjIKb08Hz7deDH8BQJj
|
||||||
|
YcUIBQkUsaQDAAoJEL08Hz7deDH8PysP/jN45LeLMjiiGAr090sRtRNqmvljvWC4
|
||||||
|
v1DlXxuLwCJFhB0U8cZMvx7uUU2PDJodecGiKunNBYAuz98WjMCTxMNnfT+cgkxv
|
||||||
|
lSmfa2wjz3l/otHWaeyLTfn48SBbSd/RoFF8sH2OaqWIde8iJ6n6OvGVluNboL8g
|
||||||
|
+ZL+O28Du+tsnZ4v7WNNJGBHJBOupaB19/ConKR/fUC8WlFV8WTC/6egWB6TbNjU
|
||||||
|
RUt/EPsc4hieU/bodJKmzYSVQcVoR/7x+wAnMNJrGS34tJN+2O1O9JobJVBCHsk5
|
||||||
|
yMhs2XLrSIys5Xby1qFWk7zmdKP1NZaSeIh+4xXtbzURtO28Xqmry76s0tznqfss
|
||||||
|
uy323+Hdp8ynXP6MuDE/nlPQVI2BMbfCvMQzSp3dSRhq2+siYg2qoL0QNAaXAPUU
|
||||||
|
OxdH2ee84Hzx60s9kdnw5EHHQ6KZiCvuSABog0kldDAdIl8I2Kc8DtzZVBLPSWp3
|
||||||
|
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
|
||||||
|
=DXwP
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
BIN
public/manifest/favicon-192.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
public/manifest/favicon-512.png
Normal file
After Width: | Height: | Size: 11 KiB |
1
public/manifest/manifest.webmanifest
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"name":"matthias kretschmann","shortName":"mk","icons":[{"src":"/manifest/favicon-192.png","type":"image/png","sizes":"192x192"},{"src":"/manifest/favicon-512.png","type":"image/png","sizes":"512x512"}]}
|
@ -1,87 +1,83 @@
|
|||||||
import { favicons, FaviconImage } from 'favicons'
|
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
import ico from 'sharp-ico'
|
||||||
|
|
||||||
const imagesDirectory = path.resolve(path.join(process.cwd(), 'src', 'images'))
|
const imagesSourcePath = path.resolve(path.join(process.cwd(), 'src', 'images'))
|
||||||
const source = `${imagesDirectory}/favicon.png`
|
const faviconSource = `${imagesSourcePath}/favicon-512.png`
|
||||||
const output = path.resolve(path.join(process.cwd(), 'public', 'favicon'))
|
const faviconSourceSvg = `${imagesSourcePath}/favicon.svg`
|
||||||
|
|
||||||
const configuration = {
|
const outputWebRoot = path.resolve(path.join(process.cwd(), 'public'))
|
||||||
path: '/favicon', // Path for overriding default icons path. `string`
|
const outputManifest = path.resolve(
|
||||||
appName: 'matthias kretschmann',
|
path.join(process.cwd(), 'public', 'manifest')
|
||||||
appShortName: 'mk',
|
)
|
||||||
appDescription: null,
|
|
||||||
developerName: null,
|
// All the sizes and meta we'll need
|
||||||
developerURL: null,
|
// https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs
|
||||||
dir: 'auto',
|
const sizes = [32, 180, 192, 512]
|
||||||
lang: 'en-US',
|
const outputMeta = `
|
||||||
appleStatusBarStyle: 'black-translucent', // Style for Apple status bar: "black-translucent", "default", "black". `string`
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
display: 'minimal-ui', // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string`
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||||
orientation: 'any', // Default orientation: "any", "natural", "portrait" or "landscape". `string`
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||||
scope: '/', // set of URLs that the browser considers within your app
|
<link rel="manifest" href="/manifest/manifest.webmanifest">
|
||||||
start_url: '/?homescreen=1',
|
`
|
||||||
background_color: '#e7eef4',
|
|
||||||
theme_color: '#e7eef4',
|
function createManifest(iconsizes: number[]) {
|
||||||
preferRelatedApplications: false,
|
const manifest = {
|
||||||
relatedApplications: undefined,
|
name: 'matthias kretschmann',
|
||||||
version: '1.0',
|
shortName: 'mk',
|
||||||
pixel_art: false, // Keeps pixels "sharp" when scaling up, for pixel art. Only supported in offline mode.
|
icons: iconsizes.map((size) => ({
|
||||||
loadManifestWithCredentials: false,
|
src: `/manifest/favicon-${size}.png`,
|
||||||
manifestMaskable: `${imagesDirectory}/logo.svg`, // 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`
|
type: 'image/png',
|
||||||
icons: {
|
sizes: `${size}x${size}`
|
||||||
android: true,
|
}))
|
||||||
appleIcon: true,
|
|
||||||
appleStartup: false,
|
|
||||||
favicons: true,
|
|
||||||
windows: true,
|
|
||||||
yandex: false
|
|
||||||
}
|
}
|
||||||
|
fs.writeFileSync(
|
||||||
|
`${outputManifest}/manifest.webmanifest`,
|
||||||
|
JSON.stringify(manifest)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildFavicons() {
|
async function buildFavicons() {
|
||||||
try {
|
try {
|
||||||
const response = await favicons(source, configuration)
|
// Nuke all & create output folder first
|
||||||
const allFilesToWrite = response.images.concat(response.files as any)
|
fs.rmSync(outputManifest, { recursive: true, force: true })
|
||||||
|
fs.rmSync(`${outputWebRoot}/apple-touch-icon.png`, { force: true })
|
||||||
|
fs.rmSync(`${outputWebRoot}/favicon.ico`, { force: true })
|
||||||
|
fs.mkdirSync(outputManifest, { recursive: true })
|
||||||
|
|
||||||
fs.rmSync(output, { recursive: true, force: true })
|
// copy over the svg, as it's handcrafted
|
||||||
|
fs.copyFileSync(faviconSourceSvg, `${outputWebRoot}/favicon.svg`)
|
||||||
|
|
||||||
allFilesToWrite.forEach((file) => {
|
// generate all the rest
|
||||||
const { name, contents } = file
|
await Promise.all(
|
||||||
const destination = `${output}/${name}`
|
sizes.map(async (size) => {
|
||||||
|
let destination = `${outputManifest}/favicon-${size}.png`
|
||||||
|
if (size === 180) destination = `${outputWebRoot}/apple-touch-icon.png`
|
||||||
|
|
||||||
try {
|
if (size === 32) {
|
||||||
fs.readFileSync(destination, 'utf8')
|
await ico.sharpsToIco(
|
||||||
} catch (error) {
|
[sharp(faviconSource)],
|
||||||
// if there is no file, get data and write a fresh file
|
`${outputWebRoot}/favicon.ico`,
|
||||||
if (error.code === 'ENOENT') {
|
{ sizes: [32, 24, 16], resizeOptions: {} }
|
||||||
try {
|
)
|
||||||
fs.mkdirSync(output, { recursive: true })
|
fs.rmSync(destination, { force: true })
|
||||||
fs.writeFileSync(destination, contents)
|
} else {
|
||||||
} catch (error) {
|
await sharp(faviconSource).resize(size, size).toFile(destination)
|
||||||
throw new Error("Couldn't write favicon file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const destinationHtml = `${output}/_meta.html`
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.readFileSync(destinationHtml, 'utf8')
|
|
||||||
} catch (error) {
|
|
||||||
// if there is no file, get data and write a fresh file
|
|
||||||
if (error.code === 'ENOENT') {
|
|
||||||
try {
|
|
||||||
fs.mkdirSync(output, { recursive: true })
|
|
||||||
fs.writeFileSync(
|
|
||||||
destinationHtml,
|
|
||||||
response.html.reverse().toString().replaceAll(',', '')
|
|
||||||
)
|
)
|
||||||
} catch (error) {
|
|
||||||
throw new Error("Couldn't write favicon file")
|
// write out manifest
|
||||||
}
|
createManifest([192, 512])
|
||||||
}
|
|
||||||
}
|
console.log(`
|
||||||
|
-----------------------------
|
||||||
|
Favicon generation complete!
|
||||||
|
-----------------------------
|
||||||
|
Add this to src/components/Meta/Favicon.tsx:
|
||||||
|
${outputMeta}
|
||||||
|
`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error.message)
|
console.error(error.message)
|
||||||
}
|
}
|
||||||
|
@ -3,100 +3,14 @@ import Head from 'next/head'
|
|||||||
const MetaFavicons = () => {
|
const MetaFavicons = () => {
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<meta name="msapplication-config" content="/favicon/browserconfig.xml" />
|
{/*
|
||||||
<meta
|
Stop the favicon madness
|
||||||
name="msapplication-TileImage"
|
https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs
|
||||||
content="/favicon/mstile-144x144.png"
|
*/}
|
||||||
/>
|
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||||
<meta name="apple-mobile-web-app-title" content="mk" />
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||||
<meta
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||||
name="apple-mobile-web-app-status-bar-style"
|
<link rel="manifest" href="/favicon/manifest.webmanifest"></link>
|
||||||
content="black-translucent"
|
|
||||||
/>
|
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="1024x1024"
|
|
||||||
href="/favicon/apple-touch-icon-1024x1024.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="180x180"
|
|
||||||
href="/favicon/apple-touch-icon-180x180.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="167x167"
|
|
||||||
href="/favicon/apple-touch-icon-167x167.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="152x152"
|
|
||||||
href="/favicon/apple-touch-icon-152x152.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="144x144"
|
|
||||||
href="/favicon/apple-touch-icon-144x144.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="120x120"
|
|
||||||
href="/favicon/apple-touch-icon-120x120.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="114x114"
|
|
||||||
href="/favicon/apple-touch-icon-114x114.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="76x76"
|
|
||||||
href="/favicon/apple-touch-icon-76x76.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="72x72"
|
|
||||||
href="/favicon/apple-touch-icon-72x72.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="60x60"
|
|
||||||
href="/favicon/apple-touch-icon-60x60.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="apple-touch-icon"
|
|
||||||
sizes="57x57"
|
|
||||||
href="/favicon/apple-touch-icon-57x57.png"
|
|
||||||
/>
|
|
||||||
<meta name="application-name" content="matthias kretschmann" />
|
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
|
||||||
<link rel="manifest" href="/favicon/manifest.webmanifest" />
|
|
||||||
<link
|
|
||||||
rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
sizes="48x48"
|
|
||||||
href="/favicon/favicon-48x48.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
sizes="32x32"
|
|
||||||
href="/favicon/favicon-32x32.png"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
sizes="16x16"
|
|
||||||
href="/favicon/favicon-16x16.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* <link
|
|
||||||
rel="mask-icon"
|
|
||||||
href="/favicon/safari-pinned-tab.svg"
|
|
||||||
color="#000000"
|
|
||||||
/> */}
|
|
||||||
<link rel="shortcut icon" href="/favicon/favicon.ico" />
|
|
||||||
</Head>
|
</Head>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
BIN
src/images/favicon-512.png
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 5.9 KiB |
27
src/images/favicon.svg
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
>
|
||||||
|
<style>
|
||||||
|
#background {
|
||||||
|
fill: #e7eef4;
|
||||||
|
}
|
||||||
|
#logomark {
|
||||||
|
fill: #6b7f88;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
#background {
|
||||||
|
fill: #161a1b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="background" width="512" height="512" />
|
||||||
|
<path
|
||||||
|
id="logomark"
|
||||||
|
d="M397,91 L421,115 L114,421 L91,398 L397,91 Z M397,182 L421,206 L205,421 L182,398 L397,182 Z M307,91 L330,115 L114,330 L91,307 L307,91 Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 593 B |
@ -1,3 +1,12 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="146" viewBox="0 0 146 146">
|
<svg
|
||||||
<path d="M307.015625,177.53125 L317.421875,188.078125 L182.421875,322.515625 L172.4375,312.390625 L307.015625,177.53125 Z M307.015625,217.328125 L317.421875,227.875 L222.21875,322.515625 L212.234375,312.390625 L307.015625,217.328125 Z M267.359375,177.53125 L277.625,188.078125 L182.421875,282.71875 L172.4375,272.59375 L267.359375,177.53125 Z" transform="translate(-172 -177)"/>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="330"
|
||||||
|
height="330"
|
||||||
|
viewBox="0 0 330 330"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M408,226 L432,250 L125,556 L102,533 L408,226 Z M408,317 L432,341 L216,556 L193,533 L408,317 Z M318,226 L341,250 L125,465 L102,442 L318,226 Z"
|
||||||
|
transform="translate(-102 -226)"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 476 B After Width: | Height: | Size: 327 B |