@turingnova/robots
Version:
Next.js robots.tsx generator - Automatically create and serve robots.txt for Next.js applications
209 lines (192 loc) âĸ 7.64 kB
JavaScript
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
// Helper function to get domain name
function getDomainName() {
// Try to get from environment variables
const domain = process.env.NEXT_PUBLIC_DOMAIN ||
process.env.DOMAIN ||
process.env.VERCEL_URL ||
process.env.NETLIFY_URL;
if (domain) {
return domain.replace(/^https?:\/\//, '').replace(/\/$/, '');
}
// Try to get from package.json
try {
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
if (packageJson.homepage) {
const homepage = packageJson.homepage;
return homepage.replace(/^https?:\/\//, '').replace(/\/$/, '');
}
} catch (error) {
// Ignore errors
}
// Default fallback
return 'your-domain.com';
}
function createNextJsRobots() {
const cwd = process.cwd();
const appDir = path.join(cwd, 'app');
const pagesDir = path.join(cwd, 'pages');
const srcAppDir = path.join(cwd, 'src', 'app');
const srcPagesDir = path.join(cwd, 'src', 'pages');
const domainName = getDomainName();
// Try app directory first (Next.js 13+ App Router)
if (fs.existsSync(appDir)) {
console.log('đ Found existing app/ directory');
const robotsTsxPath = path.join(appDir, 'robots.tsx');
if (!fs.existsSync(robotsTsxPath)) {
const robotsTsxContent = `import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: ['/'],
disallow: ['/admin/', '/private/'],
},
sitemap: 'https://${domainName}/sitemap.xml',
}
}`;
fs.writeFileSync(robotsTsxPath, robotsTsxContent);
console.log('â
robots.tsx created in app/ directory!');
console.log('đ robots.txt will be served at your-domain.com/robots.txt');
console.log('đ Deploy your Next.js app and robots.txt will be live!');
console.log('đĄ You can also run: npx init robots');
} else {
console.log('âšī¸ robots.tsx already exists in app/ directory');
console.log('đĄ You can also run: npx init robots');
}
}
// Try src/app directory (Next.js 13+ App Router with src folder)
else if (fs.existsSync(srcAppDir)) {
console.log('đ Found existing src/app/ directory');
const robotsTsxPath = path.join(srcAppDir, 'robots.tsx');
if (!fs.existsSync(robotsTsxPath)) {
const robotsTsxContent = `import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: ['/'],
disallow: ['/admin/', '/private/'],
},
sitemap: 'https://${domainName}/sitemap.xml',
}
}`;
fs.writeFileSync(robotsTsxPath, robotsTsxContent);
console.log('â
robots.tsx created in src/app/ directory!');
console.log('đ robots.txt will be served at your-domain.com/robots.txt');
console.log('đ Deploy your Next.js app and robots.txt will be live!');
console.log('đĄ You can also run: npx init robots');
} else {
console.log('âšī¸ robots.tsx already exists in src/app/ directory');
console.log('đĄ You can also run: npx init robots');
}
}
// Fallback to pages directory (Next.js 12 and below Pages Router)
else if (fs.existsSync(pagesDir)) {
console.log('đ Found existing pages/ directory');
const robotsTsxPath = path.join(pagesDir, 'robots.tsx');
if (!fs.existsSync(robotsTsxPath)) {
const robotsTsxContent = `import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: ['/'],
disallow: ['/admin/', '/private/'],
},
sitemap: 'https://${domainName}/sitemap.xml',
}
}`;
fs.writeFileSync(robotsTsxPath, robotsTsxContent);
console.log('â
robots.tsx created in pages/ directory!');
console.log('đ robots.txt will be served at your-domain.com/robots.txt');
console.log('đ Deploy your Next.js app and robots.txt will be live!');
console.log('đĄ You can also run: npx init robots');
} else {
console.log('âšī¸ robots.tsx already exists in pages/ directory');
console.log('đĄ You can also run: npx init robots');
}
}
// Fallback to src/pages directory (Next.js 12 and below Pages Router with src folder)
else if (fs.existsSync(srcPagesDir)) {
console.log('đ Found existing src/pages/ directory');
const robotsTsxPath = path.join(srcPagesDir, 'robots.tsx');
if (!fs.existsSync(robotsTsxPath)) {
const robotsTsxContent = `import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: ['/'],
disallow: ['/admin/', '/private/'],
},
sitemap: 'https://${domainName}/sitemap.xml',
}
}`;
fs.writeFileSync(robotsTsxPath, robotsTsxContent);
console.log('â
robots.tsx created in src/pages/ directory!');
console.log('đ robots.txt will be served at your-domain.com/robots.txt');
console.log('đ Deploy your Next.js app and robots.txt will be live!');
console.log('đĄ You can also run: npx init robots');
} else {
console.log('âšī¸ robots.tsx already exists in src/pages/ directory');
console.log('đĄ You can also run: npx init robots');
}
}
// Create app directory as default (Next.js 13+ App Router)
else {
console.log('đ No app/, src/app/, pages/, or src/pages/ directory found. Creating app/ directory...');
// Create app directory if it doesn't exist
if (!fs.existsSync(appDir)) {
fs.mkdirSync(appDir, { recursive: true });
console.log('đ Created app/ directory');
}
const robotsTsxPath = path.join(appDir, 'robots.tsx');
if (!fs.existsSync(robotsTsxPath)) {
const robotsTsxContent = `import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: ['/'],
disallow: ['/admin/', '/private/'],
},
sitemap: 'https://${domainName}/sitemap.xml',
}
}`;
fs.writeFileSync(robotsTsxPath, robotsTsxContent);
console.log('â
robots.tsx created in app/ directory!');
console.log('đ robots.txt will be served at your-domain.com/robots.txt');
console.log('đ Deploy your Next.js app and robots.txt will be live!');
console.log('đĄ You can also run: npx init robots');
} else {
console.log('âšī¸ robots.tsx already exists in app/ directory');
console.log('đĄ You can also run: npx init robots');
}
}
}
function main() {
try {
const cwd = process.cwd();
const packageJsonPath = path.join(cwd, 'package.json');
// Check if package.json exists and is a Next.js project
if (fs.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
// Check for Next.js
if (packageJson.dependencies?.next || packageJson.devDependencies?.next) {
console.log('đ¤ Next.js project detected! Creating robots.tsx...');
createNextJsRobots();
} else {
console.log('â ī¸ This package is designed for Next.js projects only.');
console.log('đĄ Install Next.js first: npm install next');
}
} else {
console.log('â ī¸ No package.json found. This package is for Next.js projects only.');
}
} catch (error) {
console.log('â ī¸ Could not auto-create robots files:', error.message);
}
}
main();