Some SEO stuff
This commit is contained in:
parent
208b37ce75
commit
41c109416f
11 changed files with 121 additions and 27 deletions
|
|
@ -29,6 +29,15 @@ export default defineConfig({
|
|||
access: "public",
|
||||
optional: true,
|
||||
default: parsedDoc.marketplace.enabled
|
||||
}),
|
||||
SEO: envField.string({
|
||||
context: "client",
|
||||
access: "public",
|
||||
optional: true,
|
||||
default: JSON.stringify({
|
||||
enabled: parsedDoc.seo.enabled,
|
||||
domain: new URL(parsedDoc.seo.domain).host
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 9.6 KiB |
|
|
@ -38,6 +38,7 @@
|
|||
"@types/sequelize": "^4.28.20",
|
||||
"astro": "^4.16.13",
|
||||
"astro-icon": "^1.1.2",
|
||||
"astro-seo": "^0.8.4",
|
||||
"chalk": "^5.3.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"fastify": "^5.1.0",
|
||||
|
|
|
|||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
|
|
@ -68,6 +68,9 @@ importers:
|
|||
astro-icon:
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2
|
||||
astro-seo:
|
||||
specifier: ^0.8.4
|
||||
version: 0.8.4(typescript@5.6.3)
|
||||
chalk:
|
||||
specifier: ^5.3.0
|
||||
version: 5.3.0
|
||||
|
|
@ -155,6 +158,12 @@ packages:
|
|||
'@antfu/utils@0.7.10':
|
||||
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
|
||||
|
||||
'@astrojs/check@0.5.10':
|
||||
resolution: {integrity: sha512-vliHXM9cu/viGeKiksUM4mXfO816ohWtawTl2ADPgTsd4nUMjFiyAl7xFZhF34yy4hq4qf7jvK1F2PlR3b5I5w==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: ^5.0.0
|
||||
|
||||
'@astrojs/check@0.8.3':
|
||||
resolution: {integrity: sha512-ajcSe+ezX5jCc3dreQlWzbknzXgSGnDETNe3C1mawUOtGpO4t5z2YGaD0y+wzB84lmgPWaWZa0fKSPwLq/wUHw==}
|
||||
hasBin: true
|
||||
|
|
@ -1307,6 +1316,9 @@ packages:
|
|||
astro-icon@1.1.2:
|
||||
resolution: {integrity: sha512-2qAHBtZLYuFEIMP0Ck0edyLi5fQmJjwP2Qbv41f8L4KAJ2sra/dH7q5lCOn4q0DHVtS0w3tPG8UKQRits3UPcg==}
|
||||
|
||||
astro-seo@0.8.4:
|
||||
resolution: {integrity: sha512-Ou1vzQSXAxa0K8rtNtXNvSpYqOGEgMhh0immMxJeXmbVZac3UKCNWAoXWyOQDFYsZvBugCRSg0N1phBqPMVgCw==}
|
||||
|
||||
astro@4.16.13:
|
||||
resolution: {integrity: sha512-Mtd76+BC0zLWqoXpf9xc731AhdH4MNh5JFHYdLRvSH0Nqn48hA64dPGh/cWsJvh/DZFmC0NTZusM1Qq2gyNaVg==}
|
||||
engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
|
||||
|
|
@ -4118,6 +4130,18 @@ snapshots:
|
|||
|
||||
'@antfu/utils@0.7.10': {}
|
||||
|
||||
'@astrojs/check@0.5.10(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@astrojs/language-server': 2.15.4(typescript@5.6.3)
|
||||
chokidar: 3.6.0
|
||||
fast-glob: 3.3.2
|
||||
kleur: 4.1.5
|
||||
typescript: 5.6.3
|
||||
yargs: 17.7.2
|
||||
transitivePeerDependencies:
|
||||
- prettier
|
||||
- prettier-plugin-astro
|
||||
|
||||
'@astrojs/check@0.8.3(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@astrojs/language-server': 2.15.4(typescript@5.6.3)
|
||||
|
|
@ -5377,6 +5401,14 @@ snapshots:
|
|||
- debug
|
||||
- supports-color
|
||||
|
||||
astro-seo@0.8.4(typescript@5.6.3):
|
||||
dependencies:
|
||||
'@astrojs/check': 0.5.10(typescript@5.6.3)
|
||||
transitivePeerDependencies:
|
||||
- prettier
|
||||
- prettier-plugin-astro
|
||||
- typescript
|
||||
|
||||
astro@4.16.13(@types/node@22.9.0)(lightningcss@1.27.0)(rollup@4.27.2)(terser@5.36.0)(typescript@5.6.3):
|
||||
dependencies:
|
||||
'@astrojs/compiler': 2.10.3
|
||||
|
|
|
|||
BIN
public/logo.png
Normal file
BIN
public/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
|
|
@ -15,6 +15,10 @@ interface TomlData {
|
|||
logging: boolean;
|
||||
};
|
||||
};
|
||||
seo: {
|
||||
enabled: boolean;
|
||||
domain: string;
|
||||
};
|
||||
db: {
|
||||
name: string;
|
||||
username: string;
|
||||
|
|
@ -31,6 +35,7 @@ interface Verify {
|
|||
name: string;
|
||||
typeOF: any;
|
||||
type: any;
|
||||
verifyExtras?: () => boolean | Error;
|
||||
}
|
||||
|
||||
let doc = readFileSync(fileURLToPath(new URL("../config.toml", import.meta.url))).toString();
|
||||
|
|
@ -41,6 +46,12 @@ function verify(t: Verify[]) {
|
|||
if (typeof t[i].typeOF !== t[i].type) {
|
||||
throw new Error(`Invalid structure: "${t[i].name}" should be a(n) ${t[i].type}`);
|
||||
}
|
||||
if (t[i].verifyExtras) {
|
||||
const extra = t[i].verifyExtras();
|
||||
if (extra !== true) {
|
||||
throw extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +64,17 @@ verify([
|
|||
{ name: "server.server.port", typeOF: parsedDoc.server.server.port, type: "number" },
|
||||
{ name: "server.server.wisp", typeOF: parsedDoc.server.server.wisp, type: "boolean" },
|
||||
{ name: "server.server.logging", typeOF: parsedDoc.server.server.logging, type: "boolean" },
|
||||
{ name: "seo", typeOF: parsedDoc.seo, type: "object" },
|
||||
{ name: "seo.enabled", typeOF: parsedDoc.seo.enabled, type: "boolean" },
|
||||
{ name: "seo.domain", typeOF: parsedDoc.seo.domain, type: "string", verifyExtras: () => {
|
||||
try {
|
||||
new URL(parsedDoc.seo.domain);
|
||||
}
|
||||
catch (e) {
|
||||
return Error(e);
|
||||
}
|
||||
return true;
|
||||
}},
|
||||
{ name: "db", typeOF: parsedDoc.db, type: "object" },
|
||||
{ name: "db.name", typeOF: parsedDoc.db.name, type: "string" },
|
||||
{ name: "db.username", typeOF: parsedDoc.db.username, type: "string" },
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ async function setupDB(db: ModelStatic<CatalogModel>) {
|
|||
{
|
||||
package_name: "com.nebula.gruvbox",
|
||||
title: "Gruvbox",
|
||||
image: "gruvbox.jpeg",
|
||||
image: "gruvbox.jpg",
|
||||
author: "Nebula Services",
|
||||
version: "1.0.0",
|
||||
description: "The gruvbox theme",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import { ViewTransitions } from "astro:transitions";
|
|||
import Header from "@components/Header.astro";
|
||||
import MobileNavigation from "@components/MobileNavigation.astro";
|
||||
import SettingsLoader from "@components/settings/Loader.astro";
|
||||
import { SEO } from "astro-seo";
|
||||
import { SEO as SEOC } from "astro:env/client";
|
||||
interface Props {
|
||||
title: string;
|
||||
noHeader?: string;
|
||||
|
|
@ -11,6 +13,8 @@ interface Props {
|
|||
}
|
||||
|
||||
const { title, noHeader, description, image } = Astro.props;
|
||||
const SEOConfig = JSON.parse(SEOC);
|
||||
const Host = Astro.url.host;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
|
|
@ -18,35 +22,61 @@ const { title, noHeader, description, image } = Astro.props;
|
|||
<head>
|
||||
<SettingsLoader transition:persist />
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="description"
|
||||
content={description ? description : "Astro description"}
|
||||
<SEO
|
||||
title={title},
|
||||
titleTemplate=`${SEOConfig.enabled && Host === SEOConfig.domain ? 'Nebula | %s': '%s'}`,
|
||||
titleDefault=`${SEOConfig.enabled && Host === SEOConfig.domain ? 'Nebula': ''}`,
|
||||
description=`${SEOConfig.enabled && Host === SEOConfig.domain ? description ? description : 'A stunning and sleek web proxy with support for hundreds of popular sites.' : ''}`,
|
||||
charset="UTF-8",
|
||||
openGraph={{
|
||||
basic: {
|
||||
title: `${SEOConfig.enabled && Host === SEOConfig.domain ? 'Nebula' :''}`,
|
||||
type: 'website',
|
||||
url: `${SEOConfig.enabled && Host === SEOConfig.domain ? 'https://nebulaproxy.io' : ''}`,
|
||||
image: `${SEOConfig.enabled && Host === SEOConfig.domain ? image ? image : '/logo.png': ''}`
|
||||
},
|
||||
optional: {
|
||||
description: `${SEOConfig.enabled && Host === SEOConfig.domain ? description ? description : 'A stunning and sleek web proxy with support for hundreds of popular sites.' : ''}`
|
||||
}
|
||||
}},
|
||||
twitter={{
|
||||
card: "summary_large_image",
|
||||
title: `${SEOConfig.enabled && Host === SEOConfig.domain ? 'Nebula' : ''}`,
|
||||
description: `${SEOConfig.enabled && Host === SEOConfig.domain ? description ? description : 'A stunning and sleek web proxy with support for hundreds of popular sites.' : ''}`,
|
||||
image: `${SEOConfig.enabled && Host === SEOConfig.domain ? image ? image : '/logo.png': ''}`,
|
||||
imageAlt: `${image ? 'Catalog image' : `${SEOConfig.enabled && Host === SEOConfig.domain && "Nebula services's"} logo`}`
|
||||
}},
|
||||
extend={{
|
||||
link: [
|
||||
{ rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg', id: 'favicon' },
|
||||
{
|
||||
rel: 'preload',
|
||||
href: "https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap",
|
||||
as: 'style',
|
||||
crossorigin: 'anonymous'
|
||||
},
|
||||
{
|
||||
rel: 'preload',
|
||||
href: "https://fonts.gstatic.com/s/roboto/v32/KFOmCnqEu92Fr1Mu4mxK.woff2",
|
||||
as: 'font',
|
||||
type: 'font/woff2',
|
||||
crossorigin: 'anonymous'
|
||||
}
|
||||
],
|
||||
meta: [
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
|
||||
{ name: 'generator', content: `${Astro.generator}` }
|
||||
]
|
||||
}}
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta property="og:image" content={image ? image : ""} />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" id="favicon" />
|
||||
{/* I left this out of the SEO component as we need it to persist properly : D */}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/nebula.css"
|
||||
id="stylesheet"
|
||||
transition:persist
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
|
||||
as="style"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://fonts.gstatic.com/s/roboto/v32/KFOmCnqEu92Fr1Mu4mxK.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
<ViewTransitions />
|
||||
<ViewTransitions fallback="animate" />
|
||||
</head>
|
||||
<body class="h-full bg-primary">
|
||||
{!noHeader && <Header />}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const assetsJson = await response.json();
|
|||
<Layout
|
||||
title={`Package: ${assetsJson.title}`}
|
||||
description=`${assetsJson.title} is a package on Nebula. Start using this package on Nebula today!`
|
||||
image={assetsJson.image}
|
||||
image={`/packages/${packageName}/${assetsJson.image}`}
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap min-[1032px]:mt-16 mt-8 w-full fixed inset-0 h-full md:h-[calc(100%-4rem)] z-0 bg-primary flex-col items-center content-center justify-center lg:pb-64 font-roboto max-md:p-4"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const t = useTranslations(lang);
|
|||
import { VERSION } from "astro:env/client";
|
||||
---
|
||||
|
||||
<Layout title="Nebula">
|
||||
<Layout title="Home">
|
||||
<div
|
||||
class="flex flex-wrap mt-16 justify-center content-center w-full bg-primary fixed inset-0 h-[calc(100%-4rem)] z-0 flex-col items-center"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Loading from "@components/Loading.astro";
|
|||
import Layout from "@layouts/Layout.astro";
|
||||
---
|
||||
|
||||
<Layout title="Loading..." noHeader="true">
|
||||
<Layout title="" noHeader="true">
|
||||
<Loading />
|
||||
</Layout>
|
||||
<script>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue