diff --git a/package-lock.json b/package-lock.json
index a483b05d..f82be366 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -40048,7 +40048,7 @@
},
"packages/components": {
"name": "@portaljs/components",
- "version": "0.2.0",
+ "version": "0.3.1",
"dependencies": {
"@githubocto/flat-ui": "^0.14.1",
"@heroicons/react": "^2.0.17",
diff --git a/package.json b/package.json
index f80922fa..c385cd47 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,8 @@
{
"name": "portaljs",
- "workspaces": ["./packages/*"],
+ "workspaces": [
+ "./packages/*"
+ ],
"version": "0.0.0",
"license": "MIT",
"scripts": {
diff --git a/site/.gitignore b/site/.gitignore
index 47575e0f..4cb0e8da 100644
--- a/site/.gitignore
+++ b/site/.gitignore
@@ -35,3 +35,8 @@ yarn-error.log*
# markdowndb
markdown.db
+
+# seo
+robots.txt
+sitemap-0.xml
+sitemap.xml
diff --git a/site/components/Features.tsx b/site/components/Features.tsx
index 835336e5..19976f1d 100644
--- a/site/components/Features.tsx
+++ b/site/components/Features.tsx
@@ -58,7 +58,7 @@ export default function Features() {
>
-

+
{feature.title}
diff --git a/site/components/MDXPage.tsx b/site/components/MDXPage.tsx
index 913887c3..31e060e1 100644
--- a/site/components/MDXPage.tsx
+++ b/site/components/MDXPage.tsx
@@ -12,7 +12,6 @@ export default function MDXPage({ source, frontMatter }) {
return {children};
};
-
return (
diff --git a/site/content/config.js b/site/content/config.js
index d7a50a0d..0265e7b8 100644
--- a/site/content/config.js
+++ b/site/content/config.js
@@ -1,7 +1,7 @@
const config = {
- title: 'PortalJS',
+ title: 'PortalJS - The JavaScript framework for data portals.',
description:
- 'PortalJS is a framework for rapidly building rich data portal frontends using a modern frontend approach. PortalJS can be used to present a single dataset or build a full-scale data catalog/portal.',
+ 'PortalJS is a framework for rapidly building rich data portal frontends using a modern frontend approach.',
theme: {
default: 'dark',
toggleIcon: '/images/theme-button.svg',
@@ -36,6 +36,10 @@ const config = {
],
footerLinks: [],
nextSeo: {
+ additionalLinkTags: [
+ { rel: 'icon', href: '/favicon.ico' },
+ { rel: 'apple-touch-icon', href: '/icon.png', sizes: '120x120' },
+ ],
openGraph: {
type: 'website',
title:
diff --git a/site/content/guide/index.md b/site/content/guide/index.md
index d991dfb3..6bd11b3f 100644
--- a/site/content/guide/index.md
+++ b/site/content/guide/index.md
@@ -1,6 +1,8 @@
---
showToc: false
showSidebar: false
+title: "Markdown-based Websites Guide"
+disableTitle: true
---
@@ -79,4 +81,4 @@ Below is a screenshot of how the final website will look like:
- Visit the site! Yay! Your changes are live! 🎉
> [!tip]
-> Read full tutorial [[edit-a-website-locally|here!]]
\ No newline at end of file
+> Read full tutorial [[edit-a-website-locally|here!]]
diff --git a/site/content/howtos/index.md b/site/content/howtos/index.md
index b5d16d1c..c73760e8 100644
--- a/site/content/howtos/index.md
+++ b/site/content/howtos/index.md
@@ -1,4 +1,6 @@
-# Guides and tutorials
+---
+title: Guides and Tutorials
+---
- [[howtos/analytics|How to add web analytics?]]
- [[howtos/seo|How to customize page metadata for SEO?]]
diff --git a/site/layouts/default.tsx b/site/layouts/default.tsx
index ac4525f5..09d2919b 100644
--- a/site/layouts/default.tsx
+++ b/site/layouts/default.tsx
@@ -6,7 +6,7 @@ export default function DefaultLayout({ children, ...frontMatter }) {
{/* Default layout */}
{!frontMatter.layout && (
<>
- {frontMatter.title}
+ {!frontMatter.disableTitle && {frontMatter.title}
}
{frontMatter.author && (
{frontMatter.author}
diff --git a/site/layouts/docs.tsx b/site/layouts/docs.tsx
index e08f5d69..612eebf2 100644
--- a/site/layouts/docs.tsx
+++ b/site/layouts/docs.tsx
@@ -13,7 +13,7 @@ export const DocsLayout: React.FC
= ({ children, ...frontMatter }) => {
)}
- {title && {title}
}
+ {!frontMatter.disableTitle && title && {title}
}
diff --git a/site/next-sitemap.config.js b/site/next-sitemap.config.js
new file mode 100644
index 00000000..a9e6b66b
--- /dev/null
+++ b/site/next-sitemap.config.js
@@ -0,0 +1,5 @@
+/** @type {import('next-sitemap').IConfig} */
+module.exports = {
+ siteUrl: process.env.SITE_URL || 'https://portaljs.org',
+ generateRobotsTxt: true,
+}
diff --git a/site/package-lock.json b/site/package-lock.json
index b168c763..57d24db8 100644
--- a/site/package-lock.json
+++ b/site/package-lock.json
@@ -50,6 +50,7 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.14",
+ "next-sitemap": "^4.1.8",
"postcss": "^8.4.22",
"prettier": "^2.8.7",
"remark": "^14.0.2",
@@ -229,6 +230,12 @@
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz",
"integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg=="
},
+ "node_modules/@corex/deepmerge": {
+ "version": "4.0.43",
+ "resolved": "https://registry.npmjs.org/@corex/deepmerge/-/deepmerge-4.0.43.tgz",
+ "integrity": "sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==",
+ "dev": true
+ },
"node_modules/@docsearch/css": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.0.tgz",
@@ -7087,6 +7094,15 @@
"node": "*"
}
},
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
@@ -7330,6 +7346,39 @@
"react-dom": ">=16.0.0"
}
},
+ "node_modules/next-sitemap": {
+ "version": "4.1.8",
+ "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-4.1.8.tgz",
+ "integrity": "sha512-XAXpBHX4o89JfMgvrm0zimlZwpu2iBPXHpimJMUrqOZSc4C2oB1Lv89mxuVON9IE8HOezaM+w4GjJxcYCuGPTQ==",
+ "dev": true,
+ "funding": [
+ {
+ "url": "https://github.com/iamvishnusankar/next-sitemap.git"
+ }
+ ],
+ "dependencies": {
+ "@corex/deepmerge": "^4.0.43",
+ "@next/env": "^13.4.3",
+ "fast-glob": "^3.2.12",
+ "minimist": "^1.2.8"
+ },
+ "bin": {
+ "next-sitemap": "bin/next-sitemap.mjs",
+ "next-sitemap-cjs": "bin/next-sitemap.cjs"
+ },
+ "engines": {
+ "node": ">=14.18"
+ },
+ "peerDependencies": {
+ "next": "*"
+ }
+ },
+ "node_modules/next-sitemap/node_modules/@next/env": {
+ "version": "13.4.10",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.10.tgz",
+ "integrity": "sha512-3G1yD/XKTSLdihyDSa8JEsaWOELY+OWe08o0LUYzfuHp1zHDA8SObQlzKt+v+wrkkPcnPweoLH1ImZeUa0A1NQ==",
+ "dev": true
+ },
"node_modules/next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
diff --git a/site/package.json b/site/package.json
index 7e467d05..0da92a7a 100644
--- a/site/package.json
+++ b/site/package.json
@@ -6,6 +6,7 @@
"dev": "npm run mddb && next dev",
"build": "next build",
"prebuild": "npm run mddb && node ./scripts/fix-symlinks.mjs",
+ "postbuild": "next-sitemap",
"start": "next start",
"mddb": "mddb content"
},
@@ -52,6 +53,7 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.14",
+ "next-sitemap": "^4.1.8",
"postcss": "^8.4.22",
"prettier": "^2.8.7",
"remark": "^14.0.2",
diff --git a/site/pages/_app.tsx b/site/pages/_app.tsx
index cacf8f4b..00133045 100644
--- a/site/pages/_app.tsx
+++ b/site/pages/_app.tsx
@@ -47,7 +47,12 @@ function MyApp({ Component, pageProps }) {
defaultTheme={siteConfig.theme.default}
forcedTheme={siteConfig.theme.default ? null : 'light'}
>
-
+
{/* Global Site Tag (gtag.js) - Google Analytics */}
{siteConfig.analytics && (
diff --git a/site/pages/_document.tsx b/site/pages/_document.tsx
new file mode 100644
index 00000000..e1e9cbbb
--- /dev/null
+++ b/site/pages/_document.tsx
@@ -0,0 +1,13 @@
+import { Html, Head, Main, NextScript } from 'next/document';
+
+export default function Document() {
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/site/pages/blog.tsx b/site/pages/blog.tsx
index e15552b1..9a723cba 100644
--- a/site/pages/blog.tsx
+++ b/site/pages/blog.tsx
@@ -3,10 +3,12 @@ import computeFields from '@/lib/computeFields';
import clientPromise from '@/lib/mddb';
import { BlogsList, SimpleLayout } from '@portaljs/core';
import * as fs from 'fs';
+import {NextSeo} from 'next-seo';
export default function Blog({ blogs }) {
return (
<>
+
diff --git a/site/public/icon.png b/site/public/icon.png
new file mode 100644
index 00000000..dc790d81
Binary files /dev/null and b/site/public/icon.png differ