diff --git a/astro.config.mjs b/astro.config.mjs index 30720d0..773cc81 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -15,7 +15,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default defineConfig({ // Astro uses this full URL to generate your sitemap and canonical URLs in your final build site: SITE.domain, - base: "/", + base: SITE.baseUrl, output: "static", diff --git a/package.json b/package.json index 3615c92..ac141b9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@onwidget/astrowind", "description": "A template to make your website using Astro + Tailwind CSS.", - "version": "0.1.6", + "version": "0.2.0", "private": true, "scripts": { "dev": "astro dev", @@ -19,6 +19,7 @@ "astro": "^1.0.0", "astro-icon": "^0.7.3", "reading-time": "^1.5.0", + "slugify": "^1.6.5", "subfont": "^6.9.0" } } diff --git a/src/components/core/MetaTags.astro b/src/components/core/MetaTags.astro index 6c58a57..f11ff44 100644 --- a/src/components/core/MetaTags.astro +++ b/src/components/core/MetaTags.astro @@ -15,6 +15,8 @@ const { description = "", image: _image = defaultImage, canonical, + noindex = false, + nofollow = false } = Astro.props; const image = @@ -34,6 +36,8 @@ const image = {canonical && } + + @@ -62,4 +66,5 @@ const image = -{SITE.googleSiteVerificationId && } \ No newline at end of file +{SITE.googleSiteVerificationId && +} \ No newline at end of file diff --git a/src/components/widgets/BlogList.astro b/src/components/widgets/BlogList.astro index efabee8..2896137 100644 --- a/src/components/widgets/BlogList.astro +++ b/src/components/widgets/BlogList.astro @@ -1,31 +1,15 @@ --- import BlogListItem from "~/components/widgets/BlogListItem.astro"; -import Pagination from "~/components/widgets/Pagination.astro"; const { page } = Astro.props; --- -
-
-

- News and step-by-step guides about - AstroWind - -

-
- - +
\ No newline at end of file + \ No newline at end of file diff --git a/src/components/widgets/BlogListItem.astro b/src/components/widgets/BlogListItem.astro index fb1091d..cca1f1c 100644 --- a/src/components/widgets/BlogListItem.astro +++ b/src/components/widgets/BlogListItem.astro @@ -1,5 +1,6 @@ --- import Picture from "~/components/core/Picture.astro"; +import { getPermalink } from "~/utils/permalinks"; import { findImage } from "~/utils/findImage"; import { getFormattedDate } from "~/utils/getFormatedDate"; @@ -20,7 +21,7 @@ const image = await findImage(post.image);

+ href={getPermalink(post.slug, "post")}> {post.title}

@@ -31,7 +32,7 @@ const image = await findImage(post.image); diff --git a/src/components/widgets/BlogPost.astro b/src/components/widgets/BlogPost.astro index 76b2b2d..24a6659 100644 --- a/src/components/widgets/BlogPost.astro +++ b/src/components/widgets/BlogPost.astro @@ -9,10 +9,10 @@ const { post } = Astro.props;

- ~ {Math.ceil(post.readingTime)} min + ~ {Math.ceil(post.readingTime)} min read

+ class="px-4 sm:px-6 max-w-3xl mx-auto text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8"> {post.title}

@@ -25,7 +25,7 @@ const { post } = Astro.props; }
+ class="container mx-auto px-8 sm:px-6 max-w-3xl prose prose-lg lg:prose-xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg mt-8">
diff --git a/src/components/widgets/Error404.astro b/src/components/widgets/Error404.astro index c430ddc..2b07d14 100644 --- a/src/components/widgets/Error404.astro +++ b/src/components/widgets/Error404.astro @@ -1,4 +1,5 @@ --- +const { } = Astro.props; ---
diff --git a/src/components/widgets/Footer.astro b/src/components/widgets/Footer.astro index 9068ee1..d388f3c 100644 --- a/src/components/widgets/Footer.astro +++ b/src/components/widgets/Footer.astro @@ -7,7 +7,7 @@ const { } = Astro.props;
\ No newline at end of file diff --git a/src/components/widgets/Pagination.astro b/src/components/widgets/Pagination.astro index d4e0ed4..3ef4a8d 100644 --- a/src/components/widgets/Pagination.astro +++ b/src/components/widgets/Pagination.astro @@ -1,30 +1,25 @@ --- -const { prevUrl, nextUrl } = Astro.props; +import { Icon } from "astro-icon" +const { prevUrl, nextUrl, prevText = "Newer posts", nextText = "Older posts" } = Astro.props; --- +{(prevUrl || nextUrl) && (
-
\ No newline at end of file + +)} \ No newline at end of file diff --git a/src/components/widgets/StepsLeft.astro b/src/components/widgets/StepsLeft.astro index 1de9ebd..e06da22 100644 --- a/src/components/widgets/StepsLeft.astro +++ b/src/components/widgets/StepsLeft.astro @@ -7,7 +7,11 @@ const { } = Astro.props;
-
+
+

+ Sed ac magna sit amet risus tristique interdum. + hac. +

diff --git a/src/config.mjs b/src/config.mjs index 5dcea15..7d17344 100644 --- a/src/config.mjs +++ b/src/config.mjs @@ -1,12 +1,30 @@ export const SITE = { name: "AstroWind", + domain: "https://astrowind.vercel.app", + baseUrl: "/", title: "AstroWind — Your website with Astro + Tailwind CSS", description: "🚀 AstroWind is a free and ready to start template to make your website using Astro and Tailwind CSS.", - postsPerPage: 6, - googleAnalyticsId: false, // or "G-XXXXXXXXXX", googleSiteVerificationId: "orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M", }; + +export const BLOG = { + disabled: false, + slug: "blog", + + postsWithoutBlogSlug: true, + postsPerPage: 6, + + category: { + disabled: false, + slug: "category", // set empty to change from /category/some-slug to /some-slug + }, + + tag: { + disabled: false, + slug: "tag", + }, +}; diff --git a/src/data/posts/astrowind-template-in-depth.md b/src/data/posts/astrowind-template-in-depth.md index c76ec50..676cc79 100644 --- a/src/data/posts/astrowind-template-in-depth.md +++ b/src/data/posts/astrowind-template-in-depth.md @@ -3,6 +3,8 @@ pubDate: "Aug 08 2022" title: "AstroWind template in depth" description: "Ornare cum cursus laoreet sagittis nunc fusce posuere per euismod dis vehicula a, semper fames lacus maecenas dictumst pulvinar neque enim non potenti. Torquent hac sociosqu eleifend potenti." image: "~/assets/images/hero.jpg" +category: "Tutorials" +tags: [astro, tailwind css, front-end] --- ## Dictum integer fusce ac ridiculus et odio sollicitudin diam at diff --git a/src/data/posts/get-started-website-with-astro-tailwind-css.md b/src/data/posts/get-started-website-with-astro-tailwind-css.md index 72ffdef..4e855ca 100644 --- a/src/data/posts/get-started-website-with-astro-tailwind-css.md +++ b/src/data/posts/get-started-website-with-astro-tailwind-css.md @@ -4,6 +4,8 @@ title: "Get started with AstroWind to create a website using Astro and Tailwind description: "Lorem ipsum dolor sit amet" excerpt: "Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat" image: "~/assets/images/steps.jpg" +category: "Tutorial" +tags: [astro, tailwind css] --- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/src/data/posts/how-to-customize-astrowind-to-your-brand.md b/src/data/posts/how-to-customize-astrowind-to-your-brand.md index e42721c..12ee481 100644 --- a/src/data/posts/how-to-customize-astrowind-to-your-brand.md +++ b/src/data/posts/how-to-customize-astrowind-to-your-brand.md @@ -3,6 +3,7 @@ pubDate: "Aug 10 2022" title: "How to customize AstroWind template to suit your branding" description: "Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat" image: "~/assets/images/colors.jpg" +tags: [astro, tailwind css, theme] --- ## Congue justo vulputate nascetur convallis varius orci fringilla nulla pharetr diff --git a/src/data/posts/markdown-elements-demo-post.md b/src/data/posts/markdown-elements-demo-post.md index 185930c..6fbb118 100644 --- a/src/data/posts/markdown-elements-demo-post.md +++ b/src/data/posts/markdown-elements-demo-post.md @@ -4,6 +4,7 @@ title: "Markdown elements demo post" description: "Lorem ipsum dolor sit amet" excerpt: "Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat" image: "~/assets/images/astronaut.jpg" +tags: [markdown, astro, blog] --- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/src/data/posts/useful-resources-to-create-websites.md b/src/data/posts/useful-resources-to-create-websites.md index fda936c..6377644 100644 --- a/src/data/posts/useful-resources-to-create-websites.md +++ b/src/data/posts/useful-resources-to-create-websites.md @@ -3,6 +3,7 @@ pubDate: "Aug 09 2022" title: "Useful tools and resources to create a professional website" description: "Nibh senectus lacinia volutpat nostra taciti ac posuere, dictum ultricies dictumst luctus in vehicula, mus molestie venenatis penatibus ridiculus elementum. Phasellus sollicitudin dignissim parturient." image: "~/assets/images/tools.jpg" +tags: [front-end, tools, resources] --- ## Magna nunc senectus torquent per fusce sapien ligula tempus cra diff --git a/src/layouts/BlogLayout.astro b/src/layouts/BlogLayout.astro new file mode 100644 index 0000000..34dc1f8 --- /dev/null +++ b/src/layouts/BlogLayout.astro @@ -0,0 +1,16 @@ +--- +import Layout from "~/layouts/PageLayout.astro"; + +const { meta } = Astro.props; +--- + + +
+
+

+ +

+
+ +
+
\ No newline at end of file diff --git a/src/pages/[...blog]/[...page].astro b/src/pages/[...blog]/[...page].astro new file mode 100644 index 0000000..de1a7a5 --- /dev/null +++ b/src/pages/[...blog]/[...page].astro @@ -0,0 +1,39 @@ +--- +import { SITE, BLOG } from "~/config.mjs"; +import { fetchPosts } from "~/utils/fetchPosts"; +import Layout from "~/layouts/BlogLayout.astro"; +import BlogList from "~/components/widgets/BlogList.astro"; +import Pagination from "~/components/widgets/Pagination.astro"; +import { getCanonical, getPermalink, BLOG_BASE } from "~/utils/permalinks"; + + +export async function getStaticPaths({ paginate }) { + if (BLOG?.disabled) return []; + + const posts = await fetchPosts(); + + return paginate(posts, { + params: { blog: BLOG_BASE || undefined }, + pageSize: BLOG.postsPerPage, + }); +} + +const { page } = Astro.props; +const currentPage = page.currentPage ?? 1; + +const meta = { + title: `Blog ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`, + description: SITE.description, + canonical: getCanonical(getPermalink(page.url.current)) +} +--- + + + + News and step-by-step guides about + AstroWind + + + + + \ No newline at end of file diff --git a/src/pages/[...blog]/[slug].astro b/src/pages/[...blog]/[slug].astro new file mode 100644 index 0000000..13fe0ad --- /dev/null +++ b/src/pages/[...blog]/[slug].astro @@ -0,0 +1,33 @@ +--- +import { SITE, BLOG } from "~/config.mjs"; +import { getCanonical, getPermalink } from "~/utils/permalinks"; +import { fetchPosts } from "~/utils/fetchPosts"; +import { findImage } from "~/utils/findImage"; +import Layout from "~/layouts/PageLayout.astro"; +import BlogPost from "~/components/widgets/BlogPost.astro"; + + +export async function getStaticPaths() { + if (BLOG?.disabled) return []; + + const posts = await fetchPosts(); + + return posts.map((post) => ({ + params: { slug: post.slug, blog: BLOG.postsWithoutBlogSlug ? undefined : BLOG?.slug || undefined }, + props: { post }, + })); +} + +const { post } = Astro.props; + +const meta = { + title: `${post.title} — ${SITE.name}`, + description: post.description, + canonical: post.canonical || getCanonical(getPermalink(post.slug, "post")), + image: await findImage(post.image), +} +--- + + + + \ No newline at end of file diff --git a/src/pages/[...categories]/[category]/[...page].astro b/src/pages/[...categories]/[category]/[...page].astro new file mode 100644 index 0000000..cc5f695 --- /dev/null +++ b/src/pages/[...categories]/[category]/[...page].astro @@ -0,0 +1,47 @@ +--- + +import { SITE, BLOG } from "~/config.mjs"; +import { fetchPosts } from "~/utils/fetchPosts"; +import Layout from "~/layouts/BlogLayout.astro"; +import BlogList from "~/components/widgets/BlogList.astro"; +import Pagination from "~/components/widgets/Pagination.astro"; +import { getCanonical, getPermalink, getSlug, CATEGORY_BASE } from "~/utils/permalinks"; + + +export async function getStaticPaths({ paginate }) { + if (BLOG?.disabled || BLOG?.category?.disabled) return []; + + const posts = await fetchPosts(); + + const categories = new Set() + posts.map(post => { + typeof post.category === "string" && categories.add(post.category.toLowerCase()) + }) + + return Array.from(categories).map((category) => ( + paginate(posts.filter((post) => typeof post.category === "string" && category === post.category.toLowerCase()), { + params: { category: getSlug(category), categories: CATEGORY_BASE || undefined }, + pageSize: BLOG.postsPerPage, + props: { category } + }) + )) +} + +const { page, category } = Astro.props; + +const currentPage = page.currentPage ?? 1; + +const meta = { + title: `Category '${category}' ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`, + description: SITE.description, + canonical: getCanonical(getPermalink(page.url.current)) +} +--- + + + + Category: {category} + + + + \ No newline at end of file diff --git a/src/pages/[...tags]/[tag]/[...page].astro b/src/pages/[...tags]/[tag]/[...page].astro new file mode 100644 index 0000000..dc45b49 --- /dev/null +++ b/src/pages/[...tags]/[tag]/[...page].astro @@ -0,0 +1,46 @@ +--- +import { SITE, BLOG } from "~/config.mjs"; +import { fetchPosts } from "~/utils/fetchPosts"; +import Layout from "~/layouts/BlogLayout.astro"; +import BlogList from "~/components/widgets/BlogList.astro"; +import Pagination from "~/components/widgets/Pagination.astro"; +import { getCanonical, getPermalink, getSlug, TAG_BASE } from "~/utils/permalinks"; + + +export async function getStaticPaths({ paginate }) { + if (BLOG?.disabled || BLOG?.tag?.disabled) return []; + + const posts = await fetchPosts(); + + const tags = new Set() + posts.map(post => { + Array.isArray(post.tags) && post.tags.map(tag => tags.add(tag.toLowerCase())) + }) + + return Array.from(tags).map((tag) => ( + paginate(posts.filter((post) => Array.isArray(post.tags) && post.tags.includes(tag)), { + params: { tag: getSlug(tag), tags: TAG_BASE || undefined }, + pageSize: BLOG.postsPerPage, + props: { tag }, + }) + )) +} + +const { page, tag } = Astro.props; + +const currentPage = page.currentPage ?? 1; + +const meta = { + title: `Posts by tag '${tag}' ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`, + description: SITE.description, + canonical: getCanonical(getPermalink(page.url.current)) +} +--- + + + + Tag: {tag} + + + + \ No newline at end of file diff --git a/src/pages/blog/[...page].astro b/src/pages/blog/[...page].astro deleted file mode 100644 index d1c4e47..0000000 --- a/src/pages/blog/[...page].astro +++ /dev/null @@ -1,28 +0,0 @@ ---- -import Layout from "~/layouts/PageLayout.astro"; - -import { SITE } from "~/config.mjs"; -import { fetchPosts } from "~/utils/fetchPosts"; - -import BlogList from "~/components/widgets/BlogList.astro"; - -export async function getStaticPaths({ paginate }) { - const posts = await fetchPosts(); - - return paginate(posts, { - pageSize: SITE.postsPerPage, - }); -} - -const { page } = Astro.props; - -const currentPage = page.currentPage ?? 1; - -const title = `Blog ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`; -const description = SITE.description; -const canonical = new URL(page.url.current, Astro.site); ---- - - - - \ No newline at end of file diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro deleted file mode 100644 index 61fc6c9..0000000 --- a/src/pages/blog/[slug].astro +++ /dev/null @@ -1,29 +0,0 @@ ---- -import { SITE } from "~/config.mjs"; -import { fetchPosts } from "~/utils/fetchPosts"; -import { findImage } from "~/utils/findImage"; - -import Layout from "~/layouts/PageLayout.astro"; -import BlogPost from "~/components/widgets/BlogPost.astro"; - -export async function getStaticPaths() { - const posts = await fetchPosts(); - - return posts.map((post) => ({ - params: { slug: post.slug }, - props: { post }, - })); -} - -const { post } = Astro.props; - -const title = `${post.title} — ${SITE.name}`; -const description = post.description; -const canonical = post.canonical || new URL(`blog/${post.slug}`, Astro.site); - -const image = await findImage(post.image); ---- - - - - \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index 2cebbbb..1377576 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,7 @@ --- -import Layout from "~/layouts/PageLayout.astro"; - import { SITE } from "~/config.mjs"; +import { getCanonical, getHomePermalink } from "~/utils/permalinks"; +import Layout from "~/layouts/PageLayout.astro"; import Hero from "~/components/widgets/Hero.astro"; import BasicCTA from "~/components/widgets/BasicCTA.astro"; @@ -13,12 +13,14 @@ import StepsLeft from "~/components/widgets/StepsLeft.astro"; import HighlightedPosts from "~/components/widgets/HighlightedPosts.astro"; import Stats from "~/components/widgets/Stats.astro"; -const title = SITE.title; -const description = SITE.description; -const canonical = new URL("", Astro.site); +const meta = { + title: SITE.title, + description: SITE.description, + canonical: getCanonical(getHomePermalink()), +} --- - + diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index ce67e47..b1a0fe8 100644 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -2,6 +2,7 @@ import rss from "@astrojs/rss"; import { SITE } from "~/config.mjs"; import { fetchPosts } from "~/utils/fetchPosts"; +import { getPermalink } from "~/utils/permalinks"; const posts = await fetchPosts(); @@ -12,7 +13,7 @@ export const get = () => site: import.meta.env.SITE, items: posts.map((post) => ({ - link: `blog/${post.slug}`, + link: getPermalink(post.slug, "post"), title: post.title, description: post.description, pubDate: post.pubDate, diff --git a/src/utils/getAllImages.js b/src/utils/fetchLocalImages.js similarity index 82% rename from src/utils/getAllImages.js rename to src/utils/fetchLocalImages.js index f93be65..850f676 100644 --- a/src/utils/getAllImages.js +++ b/src/utils/fetchLocalImages.js @@ -8,7 +8,7 @@ const load = async function () { let _images; -export const getAllImages = async () => { +export const fetchLocalImages = async () => { _images = _images || load(); return await _images; }; diff --git a/src/utils/fetchPosts.js b/src/utils/fetchPosts.js index 17a142a..979612d 100644 --- a/src/utils/fetchPosts.js +++ b/src/utils/fetchPosts.js @@ -10,9 +10,9 @@ const load = async function () { return await getNormalizedPost(post); }); - const results = (await Promise.all(normalizedPosts)).sort( - (a, b) => new Date(b.pubDate).valueOf() - new Date(a.pubDate).valueOf() - ); + const results = (await Promise.all(normalizedPosts)) + .sort((a, b) => new Date(b.pubDate).valueOf() - new Date(a.pubDate).valueOf()) + .filter((post) => !post.draft); return results; }; @@ -23,3 +23,16 @@ export const fetchPosts = async () => { return await _posts; }; + +export const findPostsByIds = async (ids) => { + if (!Array.isArray(ids)) return []; + + const posts = await fetchPosts(); + + return ids.reduce(function (r, a) { + posts.some(function (el) { + return a === el.slug && r.push(el); + }); + return r; + }, []); +}; diff --git a/src/utils/findImage.js b/src/utils/findImage.js index 73fa47e..fe48151 100644 --- a/src/utils/findImage.js +++ b/src/utils/findImage.js @@ -1,4 +1,4 @@ -import { getAllImages } from "~/utils/getAllImages"; +import { fetchLocalImages } from "~/utils/fetchLocalImages"; export const findImage = async (imagePath) => { if (typeof imagePath !== "string") { @@ -13,7 +13,7 @@ export const findImage = async (imagePath) => { return null; } // For now only consume images using ~/assets alias (or absolute) - const images = await getAllImages(); + const images = await fetchLocalImages(); const key = imagePath.replace("~/", "/src/"); return typeof images[key] === "function" diff --git a/src/utils/getNormalizedPost.js b/src/utils/getNormalizedPost.js index 6e06b82..23f98cb 100644 --- a/src/utils/getNormalizedPost.js +++ b/src/utils/getNormalizedPost.js @@ -5,6 +5,7 @@ export const getNormalizedPost = async (post) => { return { pubDate: frontmatter.pubDate, + draft: frontmatter.draft, canonical: frontmatter.canonical, slug: file.split("/").pop().split(".").shift(), diff --git a/src/utils/permalinks.js b/src/utils/permalinks.js new file mode 100644 index 0000000..7d96a4f --- /dev/null +++ b/src/utils/permalinks.js @@ -0,0 +1,51 @@ +import slugify from 'slugify' +import { SITE, BLOG } from "~/config.mjs"; + +const trim = (str, ch) => { + let start = 0, end = str.length; + while(start < end && str[start] === ch) + ++start; + while(end > start && str[end - 1] === ch) + --end; + return (start > 0 || end < str.length) ? str.substring(start, end) : str; +} + +const trimSlash = (s) => trim(s, "/"); +const createPath = (...params) => "/" + params.filter((el) => !!el).join("/") + +const baseUrl = trimSlash(SITE.baseUrl); + +export const BLOG_BASE = slugify(trimSlash(BLOG.slug), { lower: true }); +export const CATEGORY_BASE = slugify(trim(BLOG?.category?.slug), { lower: true }); +export const TAG_BASE = slugify(trim(BLOG?.tag?.slug), { lower: true }); + +const cleanSlug = (slug) => trimSlash(slug); + +export const getCanonical = (path = "") => new URL(path, SITE.domain); + +export const getPermalink = (slug = "", type = "page") => { + const _slug = cleanSlug(slug); + + switch (type) { + case "category": + return createPath(baseUrl, CATEGORY_BASE, _slug) + + case "tag": + return createPath(baseUrl, TAG_BASE, _slug) + + case "post": + return createPath(baseUrl, BLOG.postsWithoutBlogSlug ? "" : BLOG_BASE, _slug); + + case "page": + default: + return createPath(baseUrl, _slug); + } +}; + +export const getBlogPermalink = () => getPermalink(BLOG_BASE); +export const getHomePermalink = () => { + const permalink = getPermalink(); + return permalink !== "/" ? permalink + "/" : permalink; +} + +export const getSlug = (text) => slugify(text); \ No newline at end of file