SEO & PWA (#1)
* Initial SEO test * Canonical URL added using envs * OG & Twitter fix * Robots.txt & meta added * Localhost support for canonical url * Initial PWA version * Icons reexported & added maskable
5
.gitignore
vendored
@@ -40,3 +40,8 @@ yarn-error.log*
|
||||
# cypress
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
|
||||
# next-pwa
|
||||
**/public/workbox-*.js*
|
||||
**/public/sw.js*
|
||||
**/public/worker-*.js*
|
||||
|
||||
@@ -1,23 +1,46 @@
|
||||
import { FC } from "react";
|
||||
import { Flex, VStack, Button, Link } from "@chakra-ui/react";
|
||||
import { Flex, VStack, Button, Link, useColorModeValue } from "@chakra-ui/react";
|
||||
import Head from "next/head";
|
||||
import Header from "./Header";
|
||||
import Footer from "./Footer";
|
||||
|
||||
type Props = {
|
||||
customTitle?: string
|
||||
customTitle?: string,
|
||||
home?: true
|
||||
[key: string]: any
|
||||
};
|
||||
|
||||
const title = "Lingva Translate";
|
||||
const description = "Alternative front-end for Google Translate, serving as a Free and Open Source translator with over a hundred languages available";
|
||||
const siteDomain = process.env["NEXT_PUBLIC_SITE_DOMAIN"];
|
||||
const url = siteDomain && (siteDomain.includes("localhost") ? "http://" : "https://") + siteDomain;
|
||||
|
||||
const Layout: FC<Props> = ({ customTitle, children }) => (
|
||||
const Layout: FC<Props> = ({ customTitle, children, home, ...props }) => (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
{customTitle ?? title}
|
||||
</title>
|
||||
<link rel="icon" href="/favicon.svg" />
|
||||
<meta name="description" content={description} />
|
||||
<meta name="robots" content={home ? "index,follow" : "noindex,nofollow"} />
|
||||
{home && <link rel="canonical" href={url} />}
|
||||
<link rel="apple-touch-icon" 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" />
|
||||
<meta name="theme-color" content={useColorModeValue("#bde3cb", "#005525")} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={url} />
|
||||
<meta property="og:locale" content="en" />
|
||||
<meta property="og:image" content={`${url}/favicon-512x512.png`} />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:width" content="512" />
|
||||
<meta property="og:image:height" content="512" />
|
||||
<meta property="og:image:alt" content={title} />
|
||||
<meta property="twitter:card" content="summary" />
|
||||
<meta property="twitter:creator" content="@thedaviddelta" />
|
||||
</Head>
|
||||
|
||||
<Button
|
||||
@@ -41,6 +64,7 @@ const Layout: FC<Props> = ({ customTitle, children }) => (
|
||||
id="main"
|
||||
flexGrow={1}
|
||||
w="full"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
|
||||
7
next.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const withPWA = require("next-pwa");
|
||||
|
||||
module.exports = withPWA({
|
||||
pwa: {
|
||||
dest: "public"
|
||||
}
|
||||
});
|
||||
@@ -19,6 +19,7 @@
|
||||
"cheerio": "^1.0.0-rc.5",
|
||||
"framer-motion": "^3.10.3",
|
||||
"next": "10.0.8",
|
||||
"next-pwa": "^5.0.6",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"react-icons": "^4.2.0"
|
||||
|
||||
@@ -58,7 +58,7 @@ const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ home, transl
|
||||
return statusCode ? (
|
||||
<CustomError statusCode={statusCode} />
|
||||
) : (
|
||||
<Layout>
|
||||
<Layout home={home}>
|
||||
<VStack px={[8, null, 24, 40]} w="full">
|
||||
<HStack px={[1, null, 3, 4]} w="full">
|
||||
<LangSelect
|
||||
|
||||
BIN
public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 738 B |
BIN
public/favicon-192x192.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/favicon-512x512.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/favicon-maskable.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
@@ -46,9 +46,9 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="389.32124"
|
||||
inkscape:cy="409.07479"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="341.82297"
|
||||
inkscape:cy="499.99149"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="g1046"
|
||||
inkscape:document-rotation="0"
|
||||
@@ -101,18 +101,16 @@
|
||||
x="85.370766"
|
||||
y="21.445843"
|
||||
ry="30.319227" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:60.2376px;line-height:1.25;font-family:sans-serif;fill:#e4f4ea;fill-opacity:1;stroke:none;stroke-width:1.50595"
|
||||
x="101.58068"
|
||||
y="87.822472"
|
||||
<g
|
||||
aria-label="语"
|
||||
transform="scale(0.98945822,1.0106541)"
|
||||
id="text892"
|
||||
transform="scale(0.98945822,1.0106541)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan890"
|
||||
x="101.58068"
|
||||
y="87.822472"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;fill:#e4f4ea;fill-opacity:1;stroke-width:1.50595">语</tspan></text>
|
||||
style="font-style:normal;font-weight:normal;font-size:60.2376px;line-height:1.25;font-family:sans-serif;fill:#e4f4ea;fill-opacity:1;stroke:none;stroke-width:1.50595">
|
||||
<path
|
||||
d="m 119.77244,48.005419 c -1.86737,-2.469741 -6.02376,-6.324948 -9.21636,-8.975402 l -2.8914,2.710692 c 3.19259,2.891405 7.16827,6.927324 9.03564,9.457303 z M 117.00151,82.34085 V 56.197732 h -12.52942 v 4.27687 h 8.31278 v 21.806011 c 0,2.469741 -1.26499,3.794968 -2.10831,4.397344 0.72285,0.963802 1.86736,2.891405 2.22879,3.975682 0.90356,-1.144515 2.46974,-2.349267 12.46918,-9.216353 -0.42166,-0.903564 -0.9638,-2.650454 -1.20475,-3.794969 z m 33.61258,-6.927324 v 10.78253 h -20.42055 v -10.78253 z m -24.69742,17.047241 h 4.27687 V 90.1115 h 20.42055 v 2.168554 h 4.39734 V 71.498082 h -29.09476 z m 22.70958,-38.190638 c -0.24096,2.529979 -0.54214,5.541859 -0.90357,8.192314 h -12.28847 c 0.60238,-2.409504 1.26499,-5.240671 1.9276,-8.192314 z m 3.3733,8.192314 c 0.4819,-3.855207 0.9638,-8.252551 1.20475,-12.04752 l -3.19259,-0.301188 -0.66261,0.24095 h -11.14396 c 0.54214,-2.289028 1.02404,-4.638295 1.4457,-6.746611 h 17.34843 v -4.035919 h -34.03424 v 4.035919 h 12.10776 c -0.36143,2.108316 -0.78309,4.457583 -1.32523,6.746611 h -8.55374 v 3.915444 h 7.65017 c -0.66261,2.951643 -1.32522,5.78281 -1.98784,8.192314 h -9.9392 v 4.096156 h 38.1304 v -4.096156 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;fill:#e4f4ea;fill-opacity:1;stroke-width:1.50595"
|
||||
id="path855" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g1031">
|
||||
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 9.2 KiB |
28
public/manifest.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "Lingva Translate",
|
||||
"short_name": "Lingva",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"lang": "en",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicon-192x192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-512x512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
},
|
||||
{
|
||||
"src": "/favicon-maskable.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"background_color": "#bde3cb",
|
||||
"theme_color": "#bde3cb"
|
||||
}
|
||||
3
public/robots.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
User-Agent: *
|
||||
Disallow: /
|
||||
Allow: /$
|
||||