sitemap metadata yada yada

Seto Elkahfi committed Dec 27, 2024 at 12:55 UTC 8c2649a37c5244bc81244d3ce7beb4ce94cf44a2
19 files changed +365 -16
app/[...slug]/page.tsx
+2
@@ -2,6 +2,7 @@ import { notFound } from "next/navigation";
2 import { Metadata } from "next";
3 import { allPages } from "contentlayer/generated";
4 import { Mdx } from "@/components/mdx-components";
5 +import AboutMedia from "@/components/about-media";
6
7 interface PageProps {
8 params: {
@@ -53,6 +54,7 @@ export default async function PagePage({ params }: PageProps) {
54 <h1>{page.title}</h1>
55 {page.description && <p className="text-xl">{page.description}</p>}
56 <hr />
57 + {page.slugAsParams === 'about' && <AboutMedia />}
58 <Mdx code={page.body.code} />
59 </article>
60 );
app/page.tsx
+8
@@ -1,10 +1,18 @@
1 import { allPosts } from "@/.contentlayer/generated";
2 import Link from "next/link";
3 +import { genPageMetadata } from "./seo";
4 +import siteMetadata from '@/content/siteMetadata'
5 +
6 +export const metadata = genPageMetadata({ title: `${siteMetadata.title}` })
7
8 export default function Home() {
9 const publishedPosts = allPosts.filter((post) => post.published)
10 return (
11 <div className="prose dark:prose-invert">
12 + <h1>smbCloudXYZ</h1>
13 + <p className="text-xl">A next-gen cloud platform powering small and medium-sized businesses.</p>
14 + <hr />
15 + <h2>Resources</h2>
16 {publishedPosts.map((post) => (
17 <article key={post._id}>
18 <Link href={post.slug}>
app/robots.ts new
+15
@@ -0,0 +1,15 @@
1 +import { MetadataRoute } from 'next'
2 +import siteMetadata from '@/content/siteMetadata'
3 +
4 +export const dynamic = 'force-static'
5 +
6 +export default function robots(): MetadataRoute.Robots {
7 + return {
8 + rules: {
9 + userAgent: '*',
10 + allow: '/',
11 + },
12 + sitemap: `${siteMetadata.siteUrl}/sitemap.xml`,
13 + host: siteMetadata.siteUrl,
14 + }
15 +}
app/seo.tsx new
+32
@@ -0,0 +1,32 @@
1 +import { Metadata } from 'next'
2 +import siteMetadata from '@/content/siteMetadata'
3 +
4 +interface PageSEOProps {
5 + title: string
6 + description?: string
7 + image?: string
8 + // eslint-disable-next-line @typescript-eslint/no-explicit-any
9 + [key: string]: any
10 +}
11 +
12 +export function genPageMetadata({ title, description, image, ...rest }: PageSEOProps): Metadata {
13 + return {
14 + title,
15 + description: description || siteMetadata.description,
16 + openGraph: {
17 + title: `${title} | ${siteMetadata.title}`,
18 + description: description || siteMetadata.description,
19 + url: './',
20 + siteName: siteMetadata.title,
21 + images: image ? [image] : [siteMetadata.socialBanner],
22 + locale: 'en_US',
23 + type: 'website',
24 + },
25 + twitter: {
26 + title: `${title} | ${siteMetadata.title}`,
27 + card: 'summary_large_image',
28 + images: image ? [image] : [siteMetadata.socialBanner],
29 + },
30 + ...rest,
31 + }
32 +}
app/sitemap.ts new
+24
@@ -0,0 +1,24 @@
1 +import { MetadataRoute } from 'next'
2 +import { allPages, allPosts } from 'contentlayer/generated'
3 +import siteMetadata from '@/content/siteMetadata'
4 +
5 +export const dynamic = 'force-static'
6 +
7 +export default function sitemap(): MetadataRoute.Sitemap {
8 + const siteUrl = siteMetadata.siteUrl
9 +
10 + const postRoutes = allPosts
11 + .filter((post) => post.published)
12 + .map((post) => ({
13 + url: `${siteUrl}/${post.slug}`,
14 + lastModified: post.lastmod || post.date,
15 + }))
16 +
17 + const pageRoutes = allPages
18 + .map((page) => ({
19 + url: `${siteUrl}/${page.slug}`,
20 + lastModified: page.lastmod,
21 + }))
22 +
23 + return [...pageRoutes, ...postRoutes]
24 +}
components/about-media.tsx new
+32
@@ -0,0 +1,32 @@
1 +import Image from "next/image";
2 +import Link from "next/link";
3 +import { FaYoutube, FaInstagram, FaFacebook } from "react-icons/fa";
4 +
5 +export default function AboutMedia() {
6 + return (
7 + <div className="text-center mb-10">
8 + <div className="flex justify-center">
9 + <Image
10 + src={"/logo.png"}
11 + alt={"smbCloudXYZ logo"}
12 + width={100}
13 + height={100}
14 + />
15 + </div>
16 + <div className="flex justify-center space-x-4">
17 + <Link href={"https://www.youtube.com/@smbcloudXYZ"} target="_blank">
18 + <FaYoutube size={30} />
19 + smbCloudXYZ
20 + </Link>
21 + <Link href={"https://instagram.com/smbcloudXYZ"} target="_blank">
22 + <FaInstagram size={30} />
23 + smbCloudXYZ
24 + </Link>
25 + <Link href={"https://facebook.com/smbcloudXYZ"} target="_blank">
26 + <FaFacebook size={30} />
27 + smbCloudXYZ
28 + </Link>
29 + </div>
30 + </div>
31 + );
32 +}
components/footer.tsx
+16 -15
@@ -1,30 +1,31 @@
1 // Generate footer
2
3 import Link from "next/link";
4 -import { FaFacebook, FaGithub, FaInstagram, FaYoutube } from "react-icons/fa";
4 +import { FaGithub } from "react-icons/fa";
5 +import { FcDebian } from "react-icons/fc";
6
7 export default function Footer() {
8 return (
8 - <footer className="py-8 text-center text-gray-500 text-sm">
9 - <div className="flex justify-center space-x-4 m-2">
9 + <footer className="py-8 px-8 text-center text-gray-500 text-sm">
10 + <div className="flex justify-center space-x-4 m-2 mb-8">
11 <Link href={"https://github.com/smbcloudXYZ"} target="_blank">
11 - <FaGithub size={30} />
12 - smbCloudXYZ
13 - </Link>
14 - <Link href={"https://www.youtube.com/@smbcloudXYZ"} target="_blank">
15 - <FaYoutube size={30} />
12 + <FaGithub size={30} className="m-2" />
13 smbCloudXYZ
14 </Link>
18 - <Link href={"https://instagram.com/smbcloudXYZ"} target="_blank">
19 - <FaInstagram size={30} />
20 - smbCloudXYZ
15 + <Link href={""} target="_blank">
16 + <FcDebian size={30} className="m-2" />
17 + Debian powered
18 </Link>
22 - <Link href={"https://facebook.com/smbcloudXYZ"} target="_blank">
23 - <FaFacebook size={30} />
24 - smbCloudXYZ
19 + </div>
20 + <div className="flex justify-center space-x-4 m-2">
21 + <Link href={"privacy-policy"}>
22 + Privacy Policy
23 </Link>
24 + <Link href={"term-of-use"}>
25 + Term of Use
26 + </Link>
27 </div>
27 - <p className="m-4">
28 + <p className="m-2">
29 &copy; {new Date().getFullYear()} <a href="https://www.smbcloud.xyz">smbCloudXYZ</a>
30 </p>
31 </footer>
components/header.tsx
+1 -1
@@ -3,7 +3,7 @@ import { ModeToggle } from "./mode-toggle";
3
4 export default function Header() {
5 return (
6 - <header>
6 + <header className="mt-4 mb-8">
7 <div className="flex items-center justify-between">
8 <ModeToggle />
9 <nav className="ml-auto text-sm font-medium space-x-6">
content/pages/about.mdx
+1
@@ -1,6 +1,7 @@
1 ---
2 title: About
3 description: A next-gen cloud platform powering small and medium-sized businesses.
4 +lastmod: "2024-12-10"
5 ---
6
7 [smbCloudXYZ](https://smbcloud.xyz) offers small and medium-sized businesses easy, on-demand access to powerful, open-source software solutions in the cloud—without the hassle of installation or expensive licenses.
content/pages/privacy-policy.mdx new
+40
@@ -0,0 +1,40 @@
1 +---
2 +title: Privacy Policy
3 +lastmod: "2024-12-10"
4 +---
5 +
6 +Welcome to **smbCloudXYZ**. Your privacy is critically important to us, and we are committed to protecting it. This Privacy Policy explains how we handle your information and how we ensure your privacy is respected.
7 +
8 +## Information We Collect
9 +
10 +We collect only the information you choose to provide to us directly. For example, this may include your name, email address, or other details you submit when contacting us or signing up for our services.
11 +
12 +## How We Use Your Information
13 +
14 +- To provide and maintain our services.
15 +- To communicate with you about updates, inquiries, or service improvements.
16 +- To ensure the security of our platform and protect against fraud or misuse.
17 +
18 +## No Cookie-Based Tracking
19 +
20 +**smbCloudXYZ** does not use cookies or any cookie-based tracking methods. We believe in respecting your privacy without employing intrusive technologies. As a result, we do not track your online activity or collect information beyond what you voluntarily provide.
21 +
22 +## Third-Party Services
23 +
24 +We may use third-party services to help us operate our platform or deliver services. These providers are vetted to ensure they comply with stringent privacy standards. No third-party cookies or trackers are implemented on our site.
25 +
26 +## Your Rights
27 +
28 +You have the right to access, update, or delete any personal information you provide us. If you wish to exercise these rights or have any questions about your data, please contact us at [privacy@smbcloud.xyz](mailto:privacy@smbcloud.xyz).
29 +
30 +## Changes to This Policy
31 +
32 +We may update this Privacy Policy from time to time. Any changes will be reflected on this page, and we encourage you to review it periodically.
33 +
34 +This Privacy Policy is effective as of 10-11-2024.
35 +
36 +## Contact Us
37 +
38 +If you have any questions or concerns about this Privacy Policy, please contact us at:
39 +
40 +- Email: [privacy@smbcloud.xyz](mailto:privacy@smbcloud.xyz)
\ No newline at end of file
content/pages/term-of-use.mdx new
+43
@@ -0,0 +1,43 @@
1 +---
2 +title: Term of Use
3 +lastmod: "2024-12-10"
4 +---
5 +
6 +Welcome to **smbCloudXYX**. By accessing or using our platform, you agree to comply with and be bound by these Terms of Use. Please read them carefully.
7 +
8 +## 1. Acceptance of Terms
9 +
10 +By accessing smbCloudXYX, you acknowledge that you have read, understood, and agreed to these terms. If you do not agree with any part of these terms, please do not use our platform.
11 +
12 +## 2. Changes to Terms
13 +
14 +We reserve the right to modify these terms at any time. Any changes will be effective immediately upon posting on our platform. Your continued use of smbCloudXYX after any modifications indicates your acceptance of the new terms.
15 +
16 +## 3. User Responsibilities
17 +
18 +You agree to use smbCloudXYX in compliance with all applicable laws and regulations. You are responsible for maintaining the confidentiality of your account information and for all activities that occur under your account.
19 +
20 +## 4. Intellectual Property
21 +
22 +All content on smbCloudXYX, including text, graphics, logos, and software, is the property of smbCloudXYX or its content suppliers and is protected by intellectual property laws. You may not reproduce, distribute, or create derivative works from any content without our express written permission.
23 +
24 +## 5. Termination
25 +
26 +We reserve the right to terminate or suspend your access to smbCloudXYX at our sole discretion, without notice, for conduct that we believe violates these terms or is harmful to other users of the platform.
27 +
28 +## 6. Disclaimer of Warranties
29 +
30 +smbCloudXYX is provided *"as is"* and *"as available"* without warranties of any kind, either express or implied. We do not warrant that the platform will be uninterrupted or error-free.
31 +
32 +## 7. Limitation of Liability
33 +
34 +In no event shall smbCloudXYX be liable for any indirect, incidental, special, or consequential damages arising out of or in connection with your use of the platform.
35 +
36 +## 8. Governing Law
37 +
38 +These terms shall be governed by and construed in accordance with the laws of the jurisdiction in which smbCloudXYX operates, without regard to its conflict of law principles.
39 +
40 +## 9. Contact Information
41 +
42 +If you have any questions about these Terms of Use, please contact us at [support@smbcloud.xyz](mailto:support@smbcloud.xyz).
43 +
content/posts/cli.mdx new
+38
@@ -0,0 +1,38 @@
1 +---
2 +title: smbCloudXYZ CLI
3 +description: smbCloudXYZ command line interface.
4 +date: "2024-11-10"
5 +lastmod: "2024-12-10"
6 +published: true
7 +---
8 +
9 +## Installation
10 +
11 +One can install smbCloudXYZ CLI in different ways depends on package manager or preferences.
12 +
13 +### With Cargo
14 +
15 +This is the native installation
16 +
17 +```bash
18 +cargo install smbpndk-cli
19 +```
20 +
21 +### Homebrew (MacOS/Linux)
22 +
23 +```bash
24 +brew tap smbpndk/tap
25 +brew install cli
26 +```
27 +
28 +### With NPM
29 +
30 +```
31 +npm i -g @smbpndk/cli
32 +```
33 +
34 +## Update
35 +
36 +To update the CLI tool, simply rerun the installation command.
37 +
38 +[Source](https://github.com/smbcloudXYZ/smbcloud-cli)
\ No newline at end of file
content/posts/introducing-smbcloud.mdx
+1
@@ -2,6 +2,7 @@
2 title: Introducing smbCloudXYZ
3 description: AWS/Gooogle Cloud/Microsoft Azure for small-medium enterprises.
4 date: "2024-11-10"
5 +lastmod: "2024-12-10"
6 published: true
7 ---
8
content/posts/manage-postgresql-instance-debian.mdx
+7
@@ -0,0 +1,7 @@
1 +---
2 +title: PostgreSQL x Debian
3 +description: Managed database for small-medium enterprises.
4 +date: "2024-11-10"
5 +lastmod: "2024-12-10"
6 +published: false
7 +---
content/posts/smbcloud-console.mdx
+1
@@ -2,6 +2,7 @@
2 title: smbCloudXYZ Console Beta
3 description: Cloud platform console for small-medium enterprises.
4 date: "2024-11-15"
5 +lastmod: "2024-12-10"
6 published: true
7 ---
8
content/posts/vercel-but-better.mdx
+1
@@ -2,6 +2,7 @@
2 title: Vercel But Better
3 description: smbCloudXYZ is Vercel but better for small-medium enterprises.
4 date: "2024-12-10"
5 +lastmod: "2024-12-10"
6 published: false
7 ---
8
content/siteMetadata.js new
+95
@@ -0,0 +1,95 @@
1 +/** @type {import("pliny/config").PlinyConfig } */
2 +const siteMetadata = {
3 + title: 'smbCloudXYZ | A next-gen cloud platform powering small and medium-sized businesses.',
4 + author: 'hello@smbcloud.xyz',
5 + headerTitle: 'smbCloudXYZ',
6 + description:
7 + 'smbCloudXYZ offers small and medium-sized businesses easy, on-demand access to powerful, open-source software solutions in the cloud—without the hassle of installation or expensive licenses.',
8 + language: 'en-us',
9 + theme: 'dark', // system, dark or light
10 + siteUrl: 'https://smbcloud.xyz',
11 + siteLogo: `${process.env.BASE_PATH || ''}/logo.png`,
12 + socialBanner: `${process.env.BASE_PATH || ''}/twitter-card.png`,
13 + email: 'hello@smbcloud.xyz',
14 + facebook: 'https://facebook.com/smbCloudXYZ',
15 + youtube: 'https://youtube.com/@smbCloudXYZ',
16 + instagram: 'https://www.instagram.com/smbCloudXYZ',
17 + locale: 'en-US',
18 + // set to true if you want a navbar fixed to the top
19 + stickyNav: false,
20 + analytics: {
21 + // If you want to use an analytics provider you have to add it to the
22 + // content security policy in the `next.config.js` file.
23 + // supports Plausible, Simple Analytics, Umami, Posthog or Google Analytics.
24 + // umamiAnalytics: {
25 + // We use an env variable for this site to avoid other users cloning our analytics ID
26 + // umamiWebsiteId: process.env.NEXT_UMAMI_ID, // e.g. 123e4567-e89b-12d3-a456-426614174000
27 + // You may also need to overwrite the script if you're storing data in the US - ex:
28 + // src: 'https://us.umami.is/script.js'
29 + // Remember to add 'us.umami.is' in `next.config.js` as a permitted domain for the CSP
30 + // },
31 + // plausibleAnalytics: {
32 + // plausibleDataDomain: '', // e.g. tailwind-nextjs-starter-blog.vercel.app
33 + // If you are hosting your own Plausible.
34 + // src: '', // e.g. https://plausible.my-domain.com/js/script.js
35 + // },
36 + // simpleAnalytics: {},
37 + // posthogAnalytics: {
38 + // posthogProjectApiKey: '', // e.g. 123e4567-e89b-12d3-a456-426614174000
39 + // },
40 + // googleAnalytics: {
41 + // googleAnalyticsId: '', // e.g. G-XXXXXXX
42 + // },
43 + },
44 + newsletter: {
45 + // supports mailchimp, buttondown, convertkit, klaviyo, revue, emailoctopus, beehive
46 + // Please add your .env file and modify it according to your selection
47 + // provider: 'buttondown',
48 + },
49 + comments: {
50 + // If you want to use an analytics provider you have to add it to the
51 + // content security policy in the `next.config.js` file.
52 + // Select a provider and use the environment variables associated to it
53 + // https://vercel.com/docs/environment-variables
54 + // provider: 'giscus', // supported providers: giscus, utterances, disqus
55 + giscusConfig: {
56 + // Visit the link below, and follow the steps in the 'configuration' section
57 + // https://giscus.app/
58 + repo: process.env.NEXT_PUBLIC_GISCUS_REPO,
59 + repositoryId: process.env.NEXT_PUBLIC_GISCUS_REPOSITORY_ID,
60 + category: process.env.NEXT_PUBLIC_GISCUS_CATEGORY,
61 + categoryId: process.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID,
62 + mapping: 'pathname', // supported options: pathname, url, title
63 + reactions: '1', // Emoji reactions: 1 = enable / 0 = disable
64 + // Send discussion metadata periodically to the parent window: 1 = enable / 0 = disable
65 + metadata: '0',
66 + // theme example: light, dark, dark_dimmed, dark_high_contrast
67 + // transparent_dark, preferred_color_scheme, custom
68 + theme: 'light',
69 + // theme when dark mode
70 + darkTheme: 'transparent_dark',
71 + // If the theme option above is set to 'custom`
72 + // please provide a link below to your custom theme css file.
73 + // example: https://giscus.app/themes/custom_example.css
74 + themeURL: '',
75 + // This corresponds to the `data-lang="en"` in giscus's configurations
76 + lang: 'en',
77 + },
78 + },
79 + search: {
80 + // provider: 'kbar', // kbar or algolia
81 + // kbarConfig: {
82 + // searchDocumentsPath: `${process.env.BASE_PATH || ''}/search.json`, // path to load documents to search
83 + // },
84 + // provider: 'algolia',
85 + // algoliaConfig: {
86 + // // The application ID provided by Algolia
87 + // appId: 'R2IYF7ETH7',
88 + // // Public API key: it is safe to commit it
89 + // apiKey: '599cec31baffa4868cae4e79f180729b',
90 + // indexName: 'docsearch',
91 + // },
92 + },
93 +}
94 +
95 +module.exports = siteMetadata
contentlayer.config.js
+8
@@ -24,6 +24,10 @@ export const Page = defineDocumentType(() => ({
24 description: {
25 type: "string",
26 },
27 + lastmod: {
28 + type: "date",
29 + required: true
30 + },
31 },
32 computedFields,
33 }))
@@ -44,6 +48,10 @@ export const Post = defineDocumentType(() => ({
48 type: "date",
49 required: true,
50 },
51 + lastmod: {
52 + type: "date",
53 + required: true
54 + },
55 published: {
56 type: "boolean",
57 required: true
public/twitter-card.png
Binary files /dev/null and b/public/twitter-card.png differ