diff --git a/contents/docs/installation/index.mdx b/contents/docs/installation/index.mdx
index acc955f..009aaa3 100644
--- a/contents/docs/installation/index.mdx
+++ b/contents/docs/installation/index.mdx
@@ -22,7 +22,7 @@ Click your operating system below to access the specific installation steps and
Compatible with Windows 10, Windows 11, and modern Windows Server architectures.
###
[macOS (Apple Silicon)](./installation/mac)
-Built for ARM64 architectures natively (M1, M2, M3, M4). *Note: Intel Macs are explicitly unsupported.*
+Built for ARM64 architectures natively (Apple M-Series). *Note: Intel Macs are explicitly unsupported.*
###
[Linux (AppImage)](./installation/linux)
Portable AppImage binary compatible with Ubuntu 20.04+ and most modern Debian-based distributions.
diff --git a/contents/docs/installation/linux/index.mdx b/contents/docs/installation/linux/index.mdx
index 02eada5..7020ebf 100644
--- a/contents/docs/installation/linux/index.mdx
+++ b/contents/docs/installation/linux/index.mdx
@@ -15,7 +15,7 @@ This guide explains how to install and run the **Robonito** application on Linux
Unlike traditional `.deb` packages, an AppImage is a fully portable software format that contains all dependencies in a single file without requiring a system-level installation.
-📥 **[Download Robonito for Linux (v2.5.0)](https://robonito-prod-builds.s3.ap-south-1.amazonaws.com/Robonito-2.5.0.AppImage)**
+📥 **[Download Robonito for Linux (v{{version}})](https://{{linuxBucketName}}.s3.{{region}}.amazonaws.com/Robonito-{{version}}.AppImage)**
---
@@ -30,7 +30,7 @@ Before you can run the AppImage, you must mark it as an executable binary on you
```
2. Grant execution rights using `chmod`:
```bash
- chmod +x Robonito-2.5.0.AppImage
+ chmod +x Robonito-{{version}}.AppImage
```
**Via GUI (File Manager):**
@@ -43,7 +43,7 @@ Alternatively, right-click the file, select **Properties**, go to the **Permissi
Once permissions are properly set, launch the application via your terminal:
```bash
-./Robonito-2.5.0.AppImage
+./Robonito-{{version}}.AppImage
```
Alternatively, simply double-click the file tightly inside your visual Desktop Environment to start the Robonito client.
diff --git a/contents/docs/installation/mac/index.mdx b/contents/docs/installation/mac/index.mdx
index 1ebf718..011a391 100644
--- a/contents/docs/installation/mac/index.mdx
+++ b/contents/docs/installation/mac/index.mdx
@@ -19,7 +19,7 @@ Check your hardware via `Apple Menu > About This Mac` before downloading the sof
Download the official Robonito disk image file specifically compiled for macOS ARM64 architectures:
-📥 **[Download Robonito for macOS (v2.5.0)](https://robonito-prod-builds.s3.ap-south-1.amazonaws.com/Robonito-2.5.0-arm64.dmg)**
+📥 **[Download Robonito for macOS (v{{version}})](https://{{macBucketName}}.s3.{{region}}.amazonaws.com/Robonito-{{version}}-arm64.dmg)**
---
diff --git a/contents/docs/installation/window/index.mdx b/contents/docs/installation/window/index.mdx
index 450a5bf..995d26c 100644
--- a/contents/docs/installation/window/index.mdx
+++ b/contents/docs/installation/window/index.mdx
@@ -15,13 +15,13 @@ This guide explains how to install the **Robonito** desktop application on Windo
Download the latest Robonito setup executable directly from our secure build server:
-📥 **[Download Robonito for Windows (v2.5.0)](https://robonito-prod-builds.s3.ap-south-1.amazonaws.com/Robonito-Setup-2.5.0.exe)**
+📥 **[Download Robonito for Windows (v{{version}})](https://{{winBucketName}}.s3.{{region}}.amazonaws.com/Robonito-Setup-{{version}}.exe)**
---
## 2. Execute the Setup Wizard
-1. Locate the downloaded `Robonito-Setup-2.5.0.exe` file in your Downloads folder.
+1. Locate the downloaded `Robonito-Setup-{{version}}.exe` file in your Downloads folder.
2. Double-click the file to launch the installation wizard.
### Handling Windows SmartScreen Warnings
diff --git a/contents/docs/web-testing/create-web-test/index.mdx b/contents/docs/web-testing/create-web-test/index.mdx
index ca8e058..9dc1837 100644
--- a/contents/docs/web-testing/create-web-test/index.mdx
+++ b/contents/docs/web-testing/create-web-test/index.mdx
@@ -6,7 +6,7 @@ This guide will walk you through the process of setting up and creating a new We
In Robonito, tests are systematically organized inside containers called **Test Suites**. Suites help group related functional behaviors together (e.g., "E-commerce Checkout", "User Profile Management").
-When automating web applications, ensure your test case is housed inside a designated **Web** Test Suite.
+When automating web applications, it is recommended to put your Test Cases inside a designated **Web** Test Suite.
---
diff --git a/download-config.json b/download-config.json
new file mode 100644
index 0000000..51a8367
--- /dev/null
+++ b/download-config.json
@@ -0,0 +1,7 @@
+{
+ "version": "4.1.0",
+ "region": "ap-south-1",
+ "linuxBucketName": "robonito-downloads",
+ "macBucketName": "robonito-downloads",
+ "winBucketName": "robonito-downloads"
+}
\ No newline at end of file
diff --git a/lib/markdown.ts b/lib/markdown.ts
index cd2b548..b69eddc 100644
--- a/lib/markdown.ts
+++ b/lib/markdown.ts
@@ -60,6 +60,28 @@ type BaseMdxFrontmatter = {
description: string;
};
+let cachedConfig: Record | null = null;
+
+async function loadDownloadConfig(): Promise> {
+ if (cachedConfig) return cachedConfig;
+ try {
+ const configPath = path.join(process.cwd(), "download-config.json");
+ const content = await fs.readFile(configPath, "utf-8");
+ cachedConfig = JSON.parse(content);
+ return cachedConfig || {};
+ } catch (err) {
+ console.error("Failed to load download-config.json", err);
+ return {};
+ }
+}
+
+function replacePlaceholders(content: string, config: Record): string {
+ return content.replace(/\{\{([^}]+)\}\}/g, (match, key) => {
+ const trimmedKey = key.trim();
+ return trimmedKey in config ? config[trimmedKey] : match;
+ });
+}
+
export async function getDocsForSlug(slug: string) {
// skip assets to prevent ENOENT errors on index.mdx
const assetExtensions = [".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico", ".css", ".js"];
@@ -67,7 +89,9 @@ export async function getDocsForSlug(slug: string) {
try {
const contentPath = getDocsContentPath(slug);
- const rawMdx = await fs.readFile(contentPath, "utf-8");
+ let rawMdx = await fs.readFile(contentPath, "utf-8");
+ const downloadConfig = await loadDownloadConfig();
+ rawMdx = replacePlaceholders(rawMdx, downloadConfig);
const res = await parseMdx(rawMdx);
// If title/description are missing from frontmatter, extract from content
@@ -99,7 +123,9 @@ function stripMdx(text: string) {
export async function getDocsTocs(slug: string) {
const contentPath = getDocsContentPath(slug);
- const rawMdx = await fs.readFile(contentPath, "utf-8");
+ let rawMdx = await fs.readFile(contentPath, "utf-8");
+ const downloadConfig = await loadDownloadConfig();
+ rawMdx = replacePlaceholders(rawMdx, downloadConfig);
// captures between ## - #### can modify accordingly
const headingsRegex = /^(#{2,4})\s(.+)$/gm;
let match;