Basic SSG scrapping and client-side routing
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.5",
|
||||
"next": "10.0.8",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1"
|
||||
|
||||
@@ -1,11 +1,83 @@
|
||||
import { FC } from "react";
|
||||
import { useState, useEffect, FC } from "react";
|
||||
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import Error from "next/error";
|
||||
import { googleScrape, extractSlug } from "../utils/translate";
|
||||
|
||||
const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ translation, error, initial }) => {
|
||||
if (error)
|
||||
return <Error statusCode={error} />
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [query, setQuery] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
initial?.query && setQuery(initial.query);
|
||||
}, [initial]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!query || query === initial?.query)
|
||||
return;
|
||||
|
||||
const timeout = setTimeout(() => router.push(`/auto/en/${query}`), 2000);
|
||||
return () => clearTimeout(timeout);
|
||||
}, [query]);
|
||||
|
||||
const Page: FC = () => {
|
||||
return (
|
||||
<div>
|
||||
Initial
|
||||
<div>
|
||||
<label htmlFor="query">
|
||||
Query:
|
||||
</label>
|
||||
<input type="text" id="query" value={query} onChange={e => setQuery(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
{translation}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => ({
|
||||
paths: [
|
||||
{
|
||||
params: { slug: [] }
|
||||
}
|
||||
],
|
||||
fallback: true
|
||||
});
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ params, locale }) => {
|
||||
if (!params?.slug || !Array.isArray(params.slug))
|
||||
return {
|
||||
props: {}
|
||||
};
|
||||
|
||||
const { source, target, query } = extractSlug(params.slug);
|
||||
|
||||
if (!query)
|
||||
return {
|
||||
notFound: true
|
||||
};
|
||||
|
||||
if (!source || !target)
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/${source ?? "auto"}/${target ?? "en"}/${query}`,
|
||||
permanent: true
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
...await googleScrape(source, target, query),
|
||||
initial: {
|
||||
source, target, query
|
||||
}
|
||||
},
|
||||
revalidate: 2 * 30 * 24 * 60 * 60 // 2 months
|
||||
};
|
||||
}
|
||||
|
||||
40
utils/translate.ts
Normal file
40
utils/translate.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import cheerio from "cheerio";
|
||||
|
||||
export async function googleScrape(
|
||||
source: string,
|
||||
target: string,
|
||||
query: string
|
||||
): Promise<{
|
||||
translation?: string,
|
||||
error?: number
|
||||
}> {
|
||||
const res = await fetch(`https://translate.google.com/m?sl=${source}&tl=${target}&q=${encodeURI(query)}`);
|
||||
|
||||
if (!res.ok)
|
||||
return {
|
||||
error: res.status
|
||||
};
|
||||
|
||||
const html = await res.text();
|
||||
return {
|
||||
translation: cheerio.load(html)(".result-container").text()
|
||||
};
|
||||
}
|
||||
|
||||
export function extractSlug(slug: string[]): {
|
||||
source?: string,
|
||||
target?: string,
|
||||
query?: string
|
||||
} {
|
||||
const [p1, p2, p3] = slug;
|
||||
switch (slug.length) {
|
||||
case 1:
|
||||
return { query: p1 };
|
||||
case 2:
|
||||
return { target: p1, query: p2 }
|
||||
case 3:
|
||||
return { source: p1, target: p2, query: p3 }
|
||||
default:
|
||||
return {}
|
||||
}
|
||||
}
|
||||
120
yarn.lock
120
yarn.lock
@@ -542,6 +542,11 @@ bn.js@^5.0.0, bn.js@^5.1.1:
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
|
||||
integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
|
||||
|
||||
boolbase@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
@@ -709,6 +714,30 @@ chalk@^4.0.0:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
cheerio-select-tmp@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646"
|
||||
integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==
|
||||
dependencies:
|
||||
css-select "^3.1.2"
|
||||
css-what "^4.0.0"
|
||||
domelementtype "^2.1.0"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.4.4"
|
||||
|
||||
cheerio@^1.0.0-rc.5:
|
||||
version "1.0.0-rc.5"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f"
|
||||
integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==
|
||||
dependencies:
|
||||
cheerio-select-tmp "^0.1.0"
|
||||
dom-serializer "~1.2.0"
|
||||
domhandler "^4.0.0"
|
||||
entities "~2.1.0"
|
||||
htmlparser2 "^6.0.0"
|
||||
parse5 "^6.0.0"
|
||||
parse5-htmlparser2-tree-adapter "^6.0.0"
|
||||
|
||||
chokidar@3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
|
||||
@@ -870,6 +899,22 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
|
||||
randombytes "^2.0.0"
|
||||
randomfill "^1.0.3"
|
||||
|
||||
css-select@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8"
|
||||
integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
css-what "^4.0.0"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.4.3"
|
||||
nth-check "^2.0.0"
|
||||
|
||||
css-what@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233"
|
||||
integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==
|
||||
|
||||
css.escape@1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
|
||||
@@ -983,15 +1028,45 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dom-serializer@^1.0.1, dom-serializer@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1"
|
||||
integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
entities "^2.0.0"
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
||||
|
||||
domelementtype@^2.0.1, domelementtype@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e"
|
||||
integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==
|
||||
|
||||
domhandler@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e"
|
||||
integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==
|
||||
dependencies:
|
||||
domelementtype "^2.1.0"
|
||||
|
||||
domutils@^2.4.3, domutils@^2.4.4:
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3"
|
||||
integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==
|
||||
dependencies:
|
||||
dom-serializer "^1.0.1"
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
|
||||
electron-to-chromium@^1.3.634:
|
||||
version "1.3.683"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.683.tgz#2c9ab53ff5275cf3dd49278af714d0f8975204f7"
|
||||
integrity sha512-8mFfiAesXdEdE0DhkMKO7W9U6VU/9T3VTWwZ+4g84/YMP4kgwgFtQgUxuu7FUMcvSeKSNhFQNU+WZ68BQTLT5A==
|
||||
version "1.3.684"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.684.tgz#053fbb0a4b2d5c076dfa6e1d8ecd06a3075a558a"
|
||||
integrity sha512-GV/vz2EmmtRSvfGSQ5A0Lucic//IRSDijgL15IgzbBEEnp4rfbxeUSZSlBfmsj7BQvE4sBdgfsvPzLCnp6L21w==
|
||||
|
||||
elliptic@^6.5.3:
|
||||
version "6.5.4"
|
||||
@@ -1028,6 +1103,16 @@ enquirer@^2.3.5:
|
||||
dependencies:
|
||||
ansi-colors "^4.1.1"
|
||||
|
||||
entities@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||
|
||||
entities@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
|
||||
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
|
||||
|
||||
error-ex@^1.2.0:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||
@@ -1531,6 +1616,16 @@ hosted-git-info@^2.1.4:
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
|
||||
htmlparser2@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.1.tgz#422521231ef6d42e56bd411da8ba40aa36e91446"
|
||||
integrity sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.4.4"
|
||||
entities "^2.0.0"
|
||||
|
||||
http-errors@1.7.3:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
|
||||
@@ -2061,6 +2156,13 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
nth-check@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125"
|
||||
integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@@ -2215,6 +2317,18 @@ parse-json@^2.2.0:
|
||||
dependencies:
|
||||
error-ex "^1.2.0"
|
||||
|
||||
parse5-htmlparser2-tree-adapter@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
||||
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
|
||||
dependencies:
|
||||
parse5 "^6.0.1"
|
||||
|
||||
parse5@^6.0.0, parse5@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||
|
||||
path-browserify@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
|
||||
|
||||
Reference in New Issue
Block a user