# MM Agro Science — Self-Hosting, SEO & Analytics Guide

This project can be deployed to a server you control with **Node.js 22+**, **MySQL 8+** (or a compatible TiDB instance), HTTPS, and a configured domain name. It includes a first-party analytics dashboard, `/robots.txt`, and a dynamic `/sitemap.xml`.

> **Important:** The current CMS login is built around the existing Manus OAuth integration. Before a fully independent production deployment, replace or reconfigure `server/_core/oauth.ts` for your own authentication provider and your own approved CMS administrator accounts. Do not expose `/admin` without a secure authentication configuration.

## 1. Server requirements

| Requirement | Recommended setup |
|---|---|
| Runtime | Node.js 22 LTS and pnpm 10 |
| Database | MySQL 8+ with a dedicated database and least-privilege application user |
| Web server | Nginx or Caddy as an HTTPS reverse proxy |
| Domain | A/CNAME record pointing to the hosting server |
| Media files | An S3-compatible bucket/CDN for production media uploads |

## 2. Environment variables

Create environment values on the server; never commit a real `.env` file.

```bash
NODE_ENV=production
PORT=3000
DATABASE_URL=mysql://APP_USER:STRONG_PASSWORD@127.0.0.1:3306/mm_agro_science
JWT_SECRET=REPLACE_WITH_A_LONG_RANDOM_SECRET

# Your final HTTPS website domain. The sitemap/robots routes use this value.
CANONICAL_ORIGIN=https://www.yourdomain.com
SITE_NAME=MM Agro Science Ltd.

```

The current application also contains Manus-specific OAuth and storage variables for the managed preview. Replace those integration paths before independent production use, as described in sections 5 and 6.

## 3. Build and run

```bash
pnpm install --frozen-lockfile
pnpm drizzle-kit migrate
pnpm build
NODE_ENV=production pnpm start
```

Use a process manager such as systemd, PM2, or your hosting provider's Node service. The application reads `PORT`; do not hardcode a production port in source.

## 4. Custom domain and HTTPS

Point `www.yourdomain.com` (and optionally the root domain) to the hosting server. Terminate TLS at Nginx/Caddy and proxy requests to the Node process.

```nginx
server {
  listen 443 ssl http2;
  server_name www.yourdomain.com;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}
```

Configure an HTTP-to-HTTPS redirect separately. Confirm that `https://www.yourdomain.com/robots.txt` and `https://www.yourdomain.com/sitemap.xml` return successfully after deployment.

## 5. Google Search Console and SEO

The source includes standard description, Open Graph, Twitter, Organization JSON-LD, canonical-origin, verification-tag, sitemap, and robots support. After the custom domain is live:

1. Add the site as a **Domain property** or **URL-prefix property** in Google Search Console.
2. For HTML-tag verification, save the token in **Admin → Analytics & SEO**. DNS verification is recommended for a fully independent server and avoids reliance on browser rendering.
3. Submit `https://www.yourdomain.com/sitemap.xml` in Search Console.
4. Check that `/robots.txt` points to the same HTTPS sitemap URL.
5. Use Search Console's URL Inspection tool to request indexing for the homepage and major pages.

> The public site is currently a React SPA. Standard metadata, sitemap, and robots support are included. A full server-side rendering conversion is a separate recommended upgrade for maximum non-JavaScript crawler and social-preview coverage.

## 6. Media storage migration

Existing CMS images use the managed `/manus-storage/` path in the preview environment. For an independent host, copy those media files to an S3-compatible bucket/CDN and update the saved CMS image URLs. Then replace the current Forge-backed uploader in `server/storage.ts` with your own S3 provider implementation and configure its credentials as host environment variables.

## 7. First-party analytics dashboard

The protected **Analytics & SEO** tab records anonymous public page views in MySQL and shows page views, anonymous visitor estimates, daily trends, top pages, and referrer hosts.

| Stored | Not stored |
|---|---|
| Random browser visitor ID, route path, referrer host, event time | IP address, name, email, account ID, raw user agent, form contents |

Visitors with browser **Do Not Track** enabled are not tracked. Traffic begins appearing once real visitors use the public site.

## 8. Security checklist before launch

- Configure an independent CMS authentication provider and restrict administrator access.
- Use HTTPS, strong database credentials, and a long random JWT secret.
- Restrict database network access to the application server.
- Configure backups for MySQL and the media bucket.
- Keep Node dependencies updated and monitor server logs.
- Remove temporary related-company placeholder data and replace it with approved information.

## 9. Namecheap cPanel test deployment: `mm.agroerp.space`

This project can be tested at `https://mm.agroerp.space` when the domain and cPanel account are in the same Namecheap account. Never share cPanel passwords, database passwords, OTPs, OAuth secrets, or private API keys in chat.

### Create the subdomain and Node application

In cPanel, use **Domains → Create A New Domain** to create `mm.agroerp.space`. Create a separate application folder outside `public_html`, such as `mm-agro-science-app`. Upload the compiled `dist/` directory, `package.json`, `cpanel-start.cjs`, the `drizzle/` migration directory, and `drizzle.config.ts`. Do not upload `node_modules`, `.git`, `.env`, or development logs.

Open **Setup Node.js App → Create Application** and use Node.js 22.x if the account provides it, Production mode, the application root folder, URL `mm.agroerp.space`, and startup file `cpanel-start.cjs`. Stop the application while uploading files, then use **Run NPM Install** and restart it after environment variables are saved. The included CommonJS bridge starts the compiled ESM server from `dist/index.js`.

### Create MySQL and environment values

In **MySQL Databases**, create a dedicated database and user, grant the user privileges, and use the cPanel-prefixed names in `DATABASE_URL`. Add these variables in the Node application's environment settings:

```text
NODE_ENV=production
CANONICAL_ORIGIN=https://mm.agroerp.space
ALLOW_SEARCH_INDEXING=false
DATABASE_URL=mysql://CPANEL_DB_USER:URL_ENCODED_PASSWORD@127.0.0.1:3306/CPANEL_DB_NAME
JWT_SECRET=USE_A_LONG_RANDOM_VALUE
```

Run `npx drizzle-kit migrate` through the cPanel virtual environment or Terminal/SSH after installing dependencies. If Terminal/SSH or the required Node application support is not available, the shared hosting plan cannot run this full-stack application as configured; ask Namecheap whether Setup Node.js App can be enabled or use a Node-capable plan.

### Test safely before public launch

Enable SSL for `mm.agroerp.space`, restart the Node application, and test the homepage, products, product details, Bengali-English switching, About, Activities, crops, Gallery, Career, Our Group, Contact, and administrator login. Also verify `https://mm.agroerp.space/robots.txt` and `https://mm.agroerp.space/sitemap.xml`. With `ALLOW_SEARCH_INDEXING=false`, the test `robots.txt` should contain `Disallow: /`; do not submit this test sitemap to Google Search Console.

Before final production use, replace or properly configure the current Manus OAuth login and Forge-backed media storage with independent authentication and S3-compatible storage. For the final domain, set `ALLOW_SEARCH_INDEXING=true`, set the CMS canonical URL to the final HTTPS domain, and then submit the final sitemap to Google Search Console.
