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",