diff --git a/docs/getting_started.md b/docs/getting_started.md
index 7265606a..ed269f7c 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -61,6 +61,28 @@ Use a short, descriptive name — for example `blog/intro-to-docker` or `blog/re
---
+:::tip Blog Quality Checklist
+Before starting any development, make sure your blog meets **all** of the following criteria. Your blog can be **rejected** if any requirement is not fulfilled:
+
+- 1. 5 backlinks to different external websites to support our documentation.
+- 2. 5 internal backlinks to other articles on recodehive.
+
+- 3. **No generic content** — avoid surface-level topics like "what is Azure" or "difference between X and Y". Write pure, high-depth technical articles with images. See [this example](https://www.recodehive.com/docs/GitHub/Maintainer-guide/milestone) for the standard we aim for. (Tip: tools like [Snagit](https://www.techsmith.com/screen-capture.html) help produce great annotated screenshots.)
+
+- 4. Image filenames must be descriptive and SEO-friendly — no random names like `screenshot123.png`.
+- 5. **Content-to-code ratio**: text should be more than code. Adsense flags pages at 60% code / 40% text - keep it the opposite. If code is long, link to GitHub and reference it in comments instead.
+
+- 6. Include a **bulleted summary section** at the top of the blog post.
+- 7. Include a **FAQ section** at the bottom.
+- 8. Use Docusaurus admonitions (`:::tip`, `:::info`, `:::note`) for callouts, tips, and cautions (see formatting guidelines below).
+- 9. Tables must be **center-aligned** - wrap them in an `:::info` block to achieve this in Docusaurus.
+- 10. Use **named code blocks** with a filename label when showing code (e.g., ` ```java title="Sample.java" `).
+- 11. When showing a query and its output together, use a **Tabs** block with separate "Query" and "Output" tabs.
+- 12. Screenshots must follow the naming convention and size guidelines below.
+:::
+
+---
+
## Step 4: Create the Blog Folder and File
All blog posts live inside the `blog/` directory. Each post gets its own folder.
@@ -149,7 +171,7 @@ After the closing `---` of your frontmatter, add the `` comment
...frontmatter...
---
-
+
Your introduction paragraph goes here. This will appear as the preview on the blog index page.
@@ -158,18 +180,168 @@ Your introduction paragraph goes here. This will appear as the preview on the bl
Body content continues here...
```
-### Formatting Tips
+### Formatting Guidelines
+
+Use `##` and `###` headings to structure your content.
+
+---
+
+#### Bulleted Summary Section (Required)
+
+Every blog must begin with a bulleted summary right after the intro paragraph. This helps readers quickly understand what they'll learn.
+
+```md
+**What you'll learn in this post:**
+- How to set up X from scratch
+- How to configure Y for production
+- Common pitfalls and how to avoid them
+```
+
+---
+
+#### Named Code Blocks (Required)
+
+Always label code blocks with a filename so readers know exactly what file they are editing:
+
+````md
+```java title="Sample.java"
+public class Hello {
+ public static void main(String[] args) {
+ System.out.println("Hello, world!");
+ }
+}
+```
+````
+
+---
+
+#### Query + Output: Use Tabs (Required)
-- Use `##` and `###` headings to structure your content.
-- Use fenced code blocks with the language name for syntax highlighting:
+When showing a database query alongside its output, use a Tabs block so both fit in a single window.
- ````md
- ```python
- print("Hello, world!")
+First, import the components at the top of your `index.md` (after frontmatter, before any content):
+
+```md
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+```
+
+Then structure your query + output like this:
+
+````md
+
+
+
+ ```sql
+ -- Create the table
+ CREATE TABLE friends (
+ id INT PRIMARY KEY,
+ name VARCHAR(100),
+ username VARCHAR(100)
+ );
+
+ -- Insert data
+ INSERT INTO friends (id, name, username) VALUES
+ (1, 'John Doe', 'johndoe'),
+ (2, 'Jane Smith', 'janesmith'),
+ (3, 'Bob Johnson', 'bobjohnson');
```
- ````
-- Use `>` for callout blockquotes and `---` for horizontal dividers between sections.
+
+
+
+ | id | name | username |
+ |----|-------------|-------------|
+ | 1 | John Doe | johndoe |
+ | 2 | Jane Smith | janesmith |
+ | 3 | Bob Johnson | bobjohnson |
+
+
+
+````
+
+:::tip
+You can add as many `` tabs as needed — for example separate tabs per subquery type, or one tab per language variant.
+:::
+
+---
+
+#### Admonitions: Tips, Notes, Info, and Cautions
+
+Use Docusaurus admonitions to highlight important information. Don't overuse them — only where they add real value.
+
+**For tips and helpful extras:**
+
+```md
+:::tip Need Git Commands?
+Check out our [comprehensive Git Commands Cheatsheet](../GitHub/setup-environment/git-commands.md)
+with 50 essential Git commands and examples.
+:::
+```
+
+**For extra context or caution:**
+
+```md
+:::info
+In the picture below, Developer 1 handles the men's shopping section, Developer 2
+deals with the women's section, and Developer 3 works on the login feature.
+:::
+```
+
+**For key feature callouts:**
+
+```md
+:::note
+Key Features of GitLab:
+- GitLab provides **built-in CI/CD pipelines**.
+- Unlike GitHub, GitLab can be **self-hosted** or used on the cloud (GitLab.com).
+- GitLab offers [Premium Plans](https://about.gitlab.com/pricing/) with advanced CI/CD and security features.
+:::
+```
+
+---
+
+#### Tables: Center Alignment via `:::info`
+
+Plain Markdown tables are left-aligned by default in Docusaurus. Wrap your table in an `:::info` block to center it:
+
+```md
+:::
+
+| Command | Description |
+|-------------|-------------------|
+| `git init` | Initialize a repo |
+| `git clone` | Clone a repo |
+
+:::
+```
+
+### Rendered Output
+
+:::info
+
+| Command | Description |
+|-------------|-------------------|
+| `git init` | Initialize a repo |
+| `git clone` | Clone a repo |
+
+:::
+
+---
+
+#### FAQ Section (Required)
+
+Every blog post must end with a FAQ section before the conclusion. Use questions your readers are likely to have:
+
+```md
+## Frequently Asked Questions
+
+**Q: Do I need to know X before starting this guide?**
+A: Basic familiarity with Y is helpful, but the guide covers everything step by step.
+
+**Q: Will this work on Windows?**
+A: Yes, the steps are cross-platform. Windows-specific commands are noted where they differ.
+```
---
@@ -188,7 +360,7 @@ Use **PNG** for UI screenshots (crisp text) and **JPEG/WebP** for photos.
### Naming Convention
-Use lowercase, hyphen-separated, numbered filenames so they sort correctly:
+Use lowercase, hyphen-separated, numbered filenames so they sort correctly and are SEO-friendly. **Never use random or auto-generated names.**
```
images/
@@ -208,20 +380,52 @@ Reference images relative to `index.md`:
Always write descriptive alt text — it improves accessibility and SEO.
+:::tip Screenshot Tool Recommendation
+Tools like [Snagit](https://www.techsmith.com/screen-capture.html) make it easy to produce annotated, professional-quality screenshots. See [this article](https://www.recodehive.com/docs/GitHub/Maintainer-guide/milestone) as a reference for the image quality standard we aim for.
+:::
+
+---
+
+## Step 9: Update the Database
+
+All blog data is linked in the database folder (`\database\blogs\index.tsx`). Update it with the following details:
+
+```json
+{
+ id: sequence_wise,
+ title: "Title of the post",
+ image: "relative path of the cover image for the blog post",
+ description: "A short (2-3) lines of description of the post",
+ slug: "The name of the blog folder (keep it exact)",
+ authors: ["your-author-id"],
+ category: "The category the blog belongs to",
+ tags: ["tags or topics the blog is related to (tools or technologies)"],
+}
+```
+
+:::note
+All details are necessary for correctly rendering the blog card on the blogs page. Take a close look and make sure everything is filled in.
+:::
+
---
-## Step 9: Preview Your Post
+## Step 10: Preview Your Post
Make sure your dev server is still running (`npm start`), then navigate to [http://localhost:3000/blog](http://localhost:3000/blog) to see your post in the listing and click into it to read the full content. Verify:
- The frontmatter title, date, and author show correctly.
- The truncate preview looks right on the blog index.
+- The bulleted summary section appears near the top.
- All images load and are properly sized.
-- Code blocks are syntax-highlighted.
+- Code blocks are syntax-highlighted and have filename labels.
+- Query/output pairs use Tabs.
+- Tables are center-aligned inside `:::info` blocks.
+- Tips and notes use the correct admonition type.
+- The FAQ section is present at the bottom.
---
-## Step 10: Commit and Push Your Changes
+## Step 11: Commit and Push Your Changes
Once you are happy with the preview, stage and commit your files:
@@ -239,13 +443,13 @@ git push origin blog/your-blog-title
---
-## Step 11: Open a Pull Request
+## Step 12: Open a Pull Request
-1. Go to your fork on GitHub — you will see a **"Compare & pull request"** banner. Click it.
-2. Set the **base repository** to `recodehive/recode-website` and **base branch** to `main`.
-3. Write a clear PR title, e.g. `blog: Add post on Your Blog Title`.
-4. In the description, briefly summarize what the post covers.
-5. Click **Create pull request**.
+- 1. Go to your fork on GitHub — you will see a **"Compare & pull request"** banner. Click it.
+- 2. Set the **base repository** to `recodehive/recode-website` and **base branch** to `main`.
+- 3. Write a clear PR title, e.g. `blog: Add post on Your Blog Title`.
+- 4. In the description, briefly summarize what the post covers.
+- 5. Click **Create pull request**.
A maintainer will review and merge your post. You may be asked to make small edits before it is approved.
@@ -268,13 +472,24 @@ git push origin main
Before submitting your PR, go through this checklist:
-- [ ] Blog folder created at `blog/your-blog-title/index.md`
-- [ ] Frontmatter is complete (title, authors, tags, date, description, draft: false)
-- [ ] Author entry exists in `blog/authors.yml`
-- [ ] `` comment placed after the intro paragraph
-- [ ] All images are in `blog/your-blog-title/images/` and named with the convention
-- [ ] Cover image is 1200 × 630 px; step screenshots are no wider than 1280 px
-- [ ] Image file sizes are under 500 KB each
-- [ ] Post previews correctly at `localhost:3000/blog`
-- [ ] Committed on a feature branch (not `main`)
-- [ ] Pull request targets `recodehive/recode-website` `main` branch
+- 1. [ ] Blog folder created at `blog/your-blog-title/index.md`
+- 2. [ ] Frontmatter is complete (title, authors, tags, date, description, draft: false)
+- 3. [ ] Author entry exists in `blog/authors.yml`
+- 4. [ ] `` comment placed after the intro paragraph
+- 5. [ ] **Bulleted summary section** included near the top of the post
+- 6. [ ] **FAQ section** included at the bottom of the post
+- 7. [ ] No generic content — article is high-depth and technical with images
+- 8. [ ] 5 external backlinks to supporting websites
+- 9. [ ] 5 internal backlinks to other recodehive articles
+- 10. [ ] Text is more than code — long code blocks link to GitHub instead
+- 11. [ ] Code blocks use filename labels — e.g., opening fence followed by `python title="app.py"`
+- 12. [ ] Query + output pairs use Tabs blocks
+- 14. [ ] Tables are wrapped in `:::info` for center alignment
+- 15. [ ] Tips, notes, and cautions use the correct Docusaurus admonition
+- 16. [ ] All images are in `blog/your-blog-title/images/` with SEO-friendly names
+- 17. [ ] Cover image is 1200 × 630 px; step screenshots are no wider than 1280 px
+- 18. [ ] Image file sizes are under 500 KB each
+- 19. [ ] Post previews correctly at `localhost:3000/blog`
+- 20. [ ] Database entry added in `\database\blogs\index.tsx`
+- 21. [ ] Committed on a feature branch (not `main`)
+- 22. [ ] Pull request targets `recodehive/recode-website` `main` branch
\ No newline at end of file
diff --git a/docs/image.png b/docs/image.png
new file mode 100644
index 00000000..57d0b044
Binary files /dev/null and b/docs/image.png differ
diff --git a/docusaurus.config.ts b/docusaurus.config.ts
index 40d02595..0a8ce5a0 100644
--- a/docusaurus.config.ts
+++ b/docusaurus.config.ts
@@ -38,7 +38,7 @@ const config: Config = {
onBrokenLinks: "throw",
// onBrokenMarkdownLinks moved to markdown.hooks
-
+
// Google Analytics and Theme Scripts
scripts: [
{
@@ -298,10 +298,10 @@ const config: Config = {
EMAILJS_TEMPLATE_ID: process.env.EMAILJS_TEMPLATE_ID || "",
algoliaSiteSearch: hasAlgoliaSiteSearch
? {
- applicationId: algoliaAppId,
- apiKey: algoliaSearchApiKey,
- indexName: algoliaIndexName,
- }
+ applicationId: algoliaAppId,
+ apiKey: algoliaSearchApiKey,
+ indexName: algoliaIndexName,
+ }
: null,
hooks: {
onBrokenMarkdownLinks: "warn",
diff --git a/package-lock.json b/package-lock.json
index ce3b812b..0365e371 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -45,6 +45,7 @@
"react-icons": "^5.5.0",
"react-slot-counter": "^3.3.1",
"rehype-katex": "^7.0.1",
+ "remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"styled-components": "^6.4.1",
"tailwind-merge": "^3.6.0",
@@ -65,7 +66,7 @@
"eslint": "^9.38.0",
"eslint-plugin-react": "^7.37.5",
"husky": "^9.1.7",
- "lint-staged": "^17.0.4",
+ "lint-staged": "^16.0.0",
"postcss": "^8.5.14",
"prettier": "^3.8.3",
"prettier-plugin-tailwindcss": "^0.6.14",
@@ -15492,9 +15493,9 @@
}
},
"node_modules/get-east-asian-width": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
- "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
+ "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -18010,28 +18011,37 @@
"license": "MIT"
},
"node_modules/lint-staged": {
- "version": "17.0.4",
- "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.4.tgz",
- "integrity": "sha512-+rU9lSUyVOZ/hDUmRLVGzyS2v73cDdQjX+XQz1AaOdIE4RysLq0HoPW2HrrgeNCLklkhi904VBU1bmgWLHVnkA==",
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz",
+ "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "listr2": "^10.2.1",
- "picomatch": "^4.0.4",
+ "commander": "^14.0.3",
+ "listr2": "^9.0.5",
+ "picomatch": "^4.0.3",
"string-argv": "^0.3.2",
- "tinyexec": "^1.1.2"
+ "tinyexec": "^1.0.4",
+ "yaml": "^2.8.2"
},
"bin": {
"lint-staged": "bin/lint-staged.js"
},
"engines": {
- "node": ">=22.22.1"
+ "node": ">=20.17"
},
"funding": {
"url": "https://opencollective.com/lint-staged"
- },
- "optionalDependencies": {
- "yaml": "^2.8.4"
+ }
+ },
+ "node_modules/lint-staged/node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
}
},
"node_modules/lint-staged/node_modules/picomatch": {
@@ -18048,20 +18058,21 @@
}
},
"node_modules/listr2": {
- "version": "10.2.1",
- "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz",
- "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz",
+ "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "cli-truncate": "^5.2.0",
- "eventemitter3": "^5.0.4",
+ "cli-truncate": "^5.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
"log-update": "^6.1.0",
"rfdc": "^1.4.1",
- "wrap-ansi": "^10.0.0"
+ "wrap-ansi": "^9.0.0"
},
"engines": {
- "node": ">=22.13.0"
+ "node": ">=20.0.0"
}
},
"node_modules/listr2/node_modules/ansi-regex": {
@@ -18090,18 +18101,26 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/listr2/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/listr2/node_modules/string-width": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz",
- "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "get-east-asian-width": "^1.5.0",
- "strip-ansi": "^7.1.2"
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
},
"engines": {
- "node": ">=20"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -18124,18 +18143,18 @@
}
},
"node_modules/listr2/node_modules/wrap-ansi": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz",
- "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==",
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
"dev": true,
"license": "MIT",
"dependencies": {
- "ansi-styles": "^6.2.3",
- "string-width": "^8.2.0",
- "strip-ansi": "^7.1.2"
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
},
"engines": {
- "node": ">=20"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
@@ -28228,7 +28247,6 @@
"integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
"dev": true,
"license": "ISC",
- "optional": true,
"bin": {
"yaml": "bin.mjs"
},
diff --git a/package.json b/package.json
index 2355cd61..ceb53b0c 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
"react-icons": "^5.5.0",
"react-slot-counter": "^3.3.1",
"rehype-katex": "^7.0.1",
+ "remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"styled-components": "^6.4.1",
"tailwind-merge": "^3.6.0",
@@ -84,7 +85,7 @@
"eslint": "^9.38.0",
"eslint-plugin-react": "^7.37.5",
"husky": "^9.1.7",
- "lint-staged": "^17.0.4",
+ "lint-staged": "^16.0.0",
"postcss": "^8.5.14",
"prettier": "^3.8.3",
"prettier-plugin-tailwindcss": "^0.6.14",
@@ -106,4 +107,4 @@
"engines": {
"node": ">=18.0"
}
-}
+}
\ No newline at end of file
diff --git a/src/database/blogs/index.tsx b/src/database/blogs/index.tsx
index f58a8455..80c10b1f 100644
--- a/src/database/blogs/index.tsx
+++ b/src/database/blogs/index.tsx
@@ -176,7 +176,8 @@ const blogs: Blog[] = [
authors: ["Aditya-Singh-Rathore"],
category: "data engineering",
tags: ["Streaming Pipelines", "Real-Time Data Processing", "Data Consistency", "Data Reliability", "Resource Consumption", "Complexity", "Data Engineering"],
-
+ },
+ {
id: 15,
title: "Azure Synapse Analytics: When to Use It (And When to Choose Fabric Instead)",
image: "/img/blogs/azure-synapse-cover.png",