✨ feat: Add SEO stuff
BIN
apps/www/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 365 B |
@@ -1 +1,14 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 500"><g clip-path="url(#a)"><circle cx="250" cy="250" r="250" fill="#fff"/><path fill="#18B6F6" d="m367.87 418.45-61.17-61.18-.94.13v-.67L175.7 227.53l32.05-31.13L188.9 87.73 99.56 199.09c-15.22 15.42-18.03 40.51-7.08 59.03l55.83 93.11a46.82 46.82 0 0 0 40.73 22.81l27.65-.27 151.18 44.68Z"/><path fill="#AC7EF4" d="m401.25 196.94-12.29-22.81-6.41-11.67-2.54-4.56-.26.26-33.66-58.63a47.07 47.07 0 0 0-41.27-23.75l-29.51.8-88.01.28a47.07 47.07 0 0 0-40.33 23.34L93.4 207l95.76-119.54L314.7 226.19l-22.3 22.67 13.35 108.54.13-.26v.26h-.26l.26.27 10.42 10.2 50.62 49.78c2.13 2 5.6-.4 4.13-2.96l-31.25-61.85 54.5-101.3 1.73-2c.67-.81 1.33-1.62 1.87-2.42a46.8 46.8 0 0 0 3.34-50.18Z"/><path fill="#fff" d="M315.1 225.65 189.18 87.6l17.9 108.14L175 227l130.5 130.27-11.75-108.14 21.37-23.48Z"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h500v500H0z"/></clipPath></defs></svg>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="48.672001"
|
||||||
|
height="36.804001"
|
||||||
|
viewBox="0 0 12.8778 9.7377253"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="layer1">
|
||||||
|
<path
|
||||||
|
d="m 2.093439,1.7855532 h 8.690922 V 2.2639978 H 2.093439 Z m 0,2.8440874 h 8.690922 V 5.1080848 H 2.093439 Z m 0,2.8440866 h 8.690922 V 7.952172 H 2.093439 Z"
|
||||||
|
style="font-size:12px;fill:#ff4f01;fill-opacity:1;fill-rule:evenodd;stroke:#ff4f01;stroke-width:1.66201;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 947 B After Width: | Height: | Size: 590 B |
@@ -1,9 +1,22 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
|
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
|
||||||
"name": "qwik-project-name",
|
"name": "Nestri",
|
||||||
"short_name": "Welcome to Qwik",
|
"short_name": "Nestri - Your games. Your rules.",
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#fff",
|
"background_color": "#fafafa",
|
||||||
"description": "A Qwik project app."
|
"description": "Nestri - Your games. Your rules.",
|
||||||
}
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#fafafa"
|
||||||
|
}
|
||||||
BIN
apps/www/public/seo/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 618 B |
BIN
apps/www/public/seo/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
apps/www/public/seo/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 625 B |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
9
apps/www/public/seo/browserconfig.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/icons/mstile-150x150.png"/>
|
||||||
|
<TileColor>#ffede5</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
||||||
BIN
apps/www/public/seo/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 573 B |
BIN
apps/www/public/seo/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 608 B |
BIN
apps/www/public/seo/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
apps/www/public/seo/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 696 B |
19
apps/www/public/seo/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M398 4232 l-48 -3 -1 -42 c-2 -188 2 -861 6 -865 2 -3 997 -5 2210
|
||||||
|
-6 l2205 -1 -2 458 -3 459 -2160 1 c-1188 1 -2181 1 -2207 -1z"/>
|
||||||
|
<path d="M350 2984 c0 -19 0 -198 0 -399 0 -201 0 -391 0 -424 l0 -58 2210 0
|
||||||
|
2210 0 0 457 0 457 -2210 0 -2210 0 0 -33z"/>
|
||||||
|
<path d="M354 1799 c-3 -6 -7 -613 -5 -844 l1 -70 2197 2 c1209 1 2204 2 2211
|
||||||
|
3 18 0 18 910 0 911 -81 4 -4401 2 -4404 -2z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 902 B |
18
apps/www/public/seo/site.webmanifest
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "Nestri",
|
||||||
|
"short_name": "Nestri",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/icons/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/icons/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#fafafa",
|
||||||
|
"background_color": "#fafafa",
|
||||||
|
"display": "standalone"}
|
||||||
69
apps/www/src/components/router-head/index.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { component$ } from "@builder.io/qwik";
|
||||||
|
import { useDocumentHead, useLocation } from "@builder.io/qwik-city";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The RouterHead component is placed inside of the document `<head>` element.
|
||||||
|
*/
|
||||||
|
export const RouterHead = component$(() => {
|
||||||
|
const head = useDocumentHead();
|
||||||
|
const loc = useLocation();
|
||||||
|
const domain = loc.url.origin;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<title>{loc.url.pathname === "/" ? "Nestri – Your games. Your rules." : `${loc.url.pathname.split("/")[1].charAt(0).toUpperCase() + loc.url.pathname.split("/")[1].slice(1)} – Nestri`}</title>
|
||||||
|
|
||||||
|
<link rel="canonical" href={loc.url.href} />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
{/**For SEO optimisation purposes refrain from SVG favicons and use PNG instead */}
|
||||||
|
{/* <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> */}
|
||||||
|
{/* <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
|
<link rel="manifest" href="/manifest.json" /> */}
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/seo/apple-touch-icon.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/seo/favicon-32x32.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/seo/favicon-16x16.png" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
{/**@ts-ignore */}
|
||||||
|
<link rel="mask-icon" href="/seo/safari-pinned-tab.svg" color="#5bbad5" />
|
||||||
|
<link rel="shortcut icon" href="/seo/favicon.ico" />
|
||||||
|
<meta name="msapplication-TileColor" content="#ffede5" />
|
||||||
|
<meta name="msapplication-config" content="/seo/browserconfig.xml" />
|
||||||
|
<meta property="og:url" content={domain} />
|
||||||
|
<meta property="twitter:url" content={domain} />
|
||||||
|
<meta property="twitter:domain" content={domain.replace("https://", "")} />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:image" content={`${domain}/seo/banner.png`} />
|
||||||
|
<meta property="twitter:image" content={`${domain}/seo/banner.png`} />
|
||||||
|
|
||||||
|
{head.meta.map((m) => (
|
||||||
|
<meta key={m.key} {...m} />
|
||||||
|
))}
|
||||||
|
|
||||||
|
{head.links.map((l) => (
|
||||||
|
<link key={l.key} {...l} />
|
||||||
|
))}
|
||||||
|
|
||||||
|
{head.styles.map((s) => (
|
||||||
|
<style
|
||||||
|
key={s.key}
|
||||||
|
{...s.props}
|
||||||
|
{...(s.props?.dangerouslySetInnerHTML
|
||||||
|
? {}
|
||||||
|
: { dangerouslySetInnerHTML: s.style })}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{head.scripts.map((s) => (
|
||||||
|
<script
|
||||||
|
key={s.key}
|
||||||
|
{...s.props}
|
||||||
|
{...(s.props?.dangerouslySetInnerHTML
|
||||||
|
? {}
|
||||||
|
: { dangerouslySetInnerHTML: s.script })}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import { component$ } from "@builder.io/qwik";
|
|
||||||
import { useDocumentHead, useLocation } from "@builder.io/qwik-city";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The RouterHead component is placed inside of the document `<head>` element.
|
|
||||||
*/
|
|
||||||
export const RouterHead = component$(() => {
|
|
||||||
const head = useDocumentHead();
|
|
||||||
const loc = useLocation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<title>{head.title}</title>
|
|
||||||
|
|
||||||
<link rel="canonical" href={loc.url.href} />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
||||||
|
|
||||||
{head.meta.map((m) => (
|
|
||||||
<meta key={m.key} {...m} />
|
|
||||||
))}
|
|
||||||
|
|
||||||
{head.links.map((l) => (
|
|
||||||
<link key={l.key} {...l} />
|
|
||||||
))}
|
|
||||||
|
|
||||||
{head.styles.map((s) => (
|
|
||||||
<style
|
|
||||||
key={s.key}
|
|
||||||
{...s.props}
|
|
||||||
{...(s.props?.dangerouslySetInnerHTML
|
|
||||||
? {}
|
|
||||||
: { dangerouslySetInnerHTML: s.style })}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{head.scripts.map((s) => (
|
|
||||||
<script
|
|
||||||
key={s.key}
|
|
||||||
{...s.props}
|
|
||||||
{...(s.props?.dangerouslySetInnerHTML
|
|
||||||
? {}
|
|
||||||
: { dangerouslySetInnerHTML: s.script })}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
RouterOutlet,
|
RouterOutlet,
|
||||||
ServiceWorkerRegister,
|
ServiceWorkerRegister,
|
||||||
} from "@builder.io/qwik-city";
|
} from "@builder.io/qwik-city";
|
||||||
import { RouterHead } from "./components/router-head/router-head";
|
import { RouterHead } from "@/components/router-head";
|
||||||
import { isDev } from "@builder.io/qwik/build";
|
import { isDev } from "@builder.io/qwik/build";
|
||||||
|
|
||||||
import "@nestri/ui/globals.css";
|
import "@nestri/ui/globals.css";
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { component$ } from "@builder.io/qwik";
|
import { component$ } from "@builder.io/qwik";
|
||||||
import type { DocumentHead } from "@builder.io/qwik-city";
|
|
||||||
|
|
||||||
export default component$(() => {
|
export default component$(() => {
|
||||||
return (
|
return (
|
||||||
@@ -7,14 +6,4 @@ export default component$(() => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const head: DocumentHead = {
|
|
||||||
title: "Welcome to Qwik",
|
|
||||||
meta: [
|
|
||||||
{
|
|
||||||
name: "description",
|
|
||||||
content: "Qwik site description",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"outDir": "tmp",
|
"outDir": "tmp",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"~/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"files": ["./.eslintrc.cjs"],
|
"files": ["./.eslintrc.cjs"],
|
||||||
|
|||||||