nextjs-analyzer
Version:
A modular tool that comprehensively analyzes Next.js projects. Includes component, performance, security, SEO, data fetching, code quality, and historical analysis features.
570 lines (569 loc) • 26.6 kB
JavaScript
/**
* English language file
*/
module.exports = {
common: {
error: "Error",
success: "Success",
warning: "Warning",
info: "Info"
},
cli: {
name: "nextjs-analyzer",
description: "A modular tool for analyzing Next.js projects",
commands: {
analyze: {
description: "Run all analysis modules",
options: {
path: "Path to the Next.js project to analyze",
output: "Path to save analysis results",
format: "Output format (text, json, or html)",
verbose: "Show detailed output"
},
messages: {
moduleSelection: "Which module would you like to run?",
formatSelection: "Which output format would you like?",
allModules: "All modules: Run all analysis modules",
runningModules: "Running modules...",
visualizing: "Visualizing results...",
completed: "Analysis completed."
}
},
listModules: {
description: "List available analysis modules",
messages: {
availableModules: "Available Analysis Modules:"
}
},
settings: {
description: "Configure application settings",
messages: {
languageSelection: "Which language would you like to use?",
languageChanged: "Language changed to: {language}",
settingsSaved: "Settings saved."
}
}
},
formats: {
text: "Text",
html: "HTML",
json: "JSON"
}
},
analyzer: {
messages: {
analyzing: "Analyzing Next.js project...",
noNextJsDirs: "Error: Next.js app or pages directory not found.",
noJsFiles: "Error: No JavaScript/TypeScript files found.",
filesFound: "{count} files found.",
analysisFailed: "Analysis failed.",
unexpectedError: "An unexpected error occurred:"
}
},
modules: {
component: {
name: "component",
description: "Analyzes server and client components in Next.js projects",
types: {
server: "Server Component",
client: "Client Component"
}
},
performance: {
name: "performance",
description: "Provides performance metrics and optimization suggestions",
imageOptimization: {
title: "Image Optimization",
fullyOptimized: "All images are optimized. Great!",
notFullyOptimized: "Out of {totalImages} images, {nonOptimizedCount} are not optimized.",
nonOptimizedImages: "Non-Optimized Images",
issues: {
noNextImage: "Next.js Image component is not used",
noWidthHeight: "Width and/or height not specified in Image component",
noPriority: "Priority attribute not used for hero/banner image"
},
recommendations: {
useNextImage: "Import next/image and use the <Image> component",
addWidthHeight: "Specify width and height to prevent CLS (Cumulative Layout Shift) issues",
addPriority: "Add priority to hero images to improve LCP (Largest Contentful Paint) metric"
}
},
bundleSize: {
title: "Bundle Size Analysis",
largeComponents: {
title: "Large Components",
noLargeComponents: "No large components detected. Great!",
recommendation: "Consider breaking the component into smaller pieces"
},
largeImports: {
title: "Large Libraries",
noLargeImports: "No large library imports detected. Great!",
recommendations: {
lodash: "Import only the functions you need: import { debounce } from \"lodash/debounce\"",
moment: "Use lighter alternatives like date-fns or day.js",
chartjs: "Import only the chart types you need",
threejs: "Use dynamic import for lazy loading",
monaco: "Use dynamic import for lazy loading",
draftjs: "Use dynamic import for lazy loading",
quill: "Use dynamic import for lazy loading",
reactBootstrap: "Import only the components you need",
materialUi: "Use the tree-shakeable version of @mui/material",
materialCore: "Import only the components you need",
mui: "Import only the components you need",
default: "Use dynamic import for lazy loading"
}
}
},
visualize: {
title: "Performance Analysis",
file: "File",
issue: "Issue",
recommendation: "Recommendation",
size: "Size",
library: "Library",
source: "Source"
}
},
security: {
name: "security",
description: "Detects security vulnerabilities and risks",
serverComponent: {
title: "Server Component Security",
noIssues: "No security issues detected in server components. Great!",
issues: {
sensitiveEnvVars: "Sensitive environment variables used directly in server component",
sqlInjection: "Potential SQL injection risk",
fileSystemAccess: "File system access with user input",
evalUsage: "Usage of eval() or new Function()"
},
recommendations: {
title: "Server Component Security",
description: "Server components may contain sensitive information. Be careful not to leak this information to the client.",
envVars: {
title: "Environment Variables",
description: "Environment variables used in server components are not included in the client bundle. However, using these variables directly in JSX can cause this information to leak to the client."
},
dataValidation: {
title: "Data Validation",
description: "Always validate and sanitize user inputs in server components."
},
sensitiveEnvVars: "Avoid sending sensitive environment variables directly to the client. Instead, use API routes to process this information securely.",
sqlInjection: "Use parameterized queries or an ORM instead of directly using user inputs in SQL queries.",
fileSystemAccess: "Using user inputs in file paths is dangerous. Validate and sanitize inputs.",
evalUsage: "Avoid using eval() and new Function() as they are vulnerable to code injection attacks."
}
},
apiRoute: {
title: "API Route Security",
noIssues: "No security issues detected in API routes. Great!",
issues: {
corsConfig: "Missing CORS configuration",
corsWildcard: "CORS configuration too broad (wildcard *)",
rateLimiting: "Missing rate limiting",
authentication: "Missing authentication check in data-modifying API endpoint",
inputValidation: "Missing input validation",
httpMethod: "Missing HTTP method check"
},
recommendations: {
title: "API Route Security",
description: "API routes are the gateways of your application to the outside world. Therefore, you should carefully implement security measures.",
cors: {
title: "CORS Configuration",
description: "CORS configuration controls which domains can access your API. Instead of using wildcard (*), allow specific domains."
},
rateLimiting: {
title: "Rate Limiting",
description: "Rate limiting restricts requests to your API and provides protection against DDoS attacks."
},
auth: {
title: "Authentication and Authorization",
description: "Always perform authentication and authorization checks in data-modifying API endpoints."
},
inputValidation: {
title: "Input Validation",
description: "Always validate and sanitize user inputs. This provides protection against injection attacks."
},
corsConfig: "Add CORS configuration to API routes. Use next-cors or manually add Access-Control-Allow-Origin header.",
corsWildcard: "Instead of wildcard (*), allow specific domains.",
rateLimiting: "Add rate limiting to API routes. You can use express-rate-limit or a similar library.",
authentication: "Add authentication check to data-modifying API endpoints.",
inputValidation: "Add input validation to API routes. You can use libraries like Joi, Yup, Zod.",
httpMethod: "Add HTTP method check to API routes. For example: if (req.method !== \"POST\") { return res.status(405).end(); }"
}
},
general: {
title: "General Security",
noIssues: "No general security issues detected. Great!",
issues: {
oldNextVersion: "Using old Next.js version ({version})",
insecurePackage: "Package with security vulnerability: {package}@{version}",
envNotIgnored: "{file} file not in .gitignore",
sensitiveEnvVar: "Environment variable containing sensitive information: {key}",
cspMissing: "Missing Content Security Policy (CSP)",
unsafeConfig: "Unsafe configuration: dangerouslyAllowSVG or dangerouslyAllowHTML"
},
recommendations: {
title: "General Security",
dependencies: {
title: "Dependency Security",
description: "Regularly update your dependencies and check for security vulnerabilities. You can use npm audit or yarn audit commands."
},
envSecurity: {
title: "Environment Variable Security",
description: "Always add .env files to .gitignore and manage sensitive information securely."
},
csp: {
title: "Content Security Policy",
description: "Content Security Policy (CSP) provides strong protection against XSS attacks. Configure CSP headers in your next.config.js file."
},
safeConfig: {
title: "Safe Configuration",
description: "Avoid unsafe configurations like dangerouslyAllowSVG, dangerouslyAllowHTML."
},
securityAudits: {
title: "Regular Security Audits",
description: "Regularly audit your application for security vulnerabilities and keep it up to date."
},
oldNextVersion: "Upgrade Next.js to the latest version for security updates.",
insecurePackage: "Upgrade {package} package to at least version {minVersion}.",
envNotIgnored: "Add {file} file to .gitignore. Sensitive information should not be stored in the repository.",
sensitiveEnvVar: "Add {file} file to .gitignore and manage sensitive information securely.",
cspMissing: "Add Content Security Policy to next.config.js file. This provides protection against XSS attacks.",
unsafeConfig: "These configurations may be vulnerable to XSS attacks. Avoid using them if possible."
}
},
visualize: {
title: "Security Analysis",
summary: "Summary",
totalIssues: "Total {count} security issues detected:",
criticalIssues: "Critical",
highIssues: "High",
mediumIssues: "Medium",
lowIssues: "Low",
detectedIssues: "Detected Issues",
recommendations: "Recommendations",
file: "File",
issue: "Issue",
severity: "Severity",
recommendation: "Recommendation"
}
},
seo: {
name: "seo",
description: "Analyzes SEO compatibility and meta tags",
metaTags: {
title: "Meta Tag Issues",
noIssues: "No meta tag issues detected. Great!",
issues: {
titleMissing: "Missing title tag",
descriptionMissing: "Missing meta description",
ogMissing: "Missing Open Graph meta tags",
twitterMissing: "Missing Twitter Card meta tags",
canonicalMissing: "Missing canonical URL",
robotsBlocking: "Robots meta tag blocking page indexing",
viewportMissing: "Missing viewport meta tag",
langMissing: "Missing HTML lang attribute"
},
recommendations: {
title: "Meta Tag Recommendations",
titleTag: "Add title tag to the page. This is very important for SEO.",
descriptionTag: "Add meta description to the page. This is the description displayed in search results.",
ogTags: "Add Open Graph meta tags for social media sharing.",
twitterTags: "Add Twitter Card meta tags for Twitter sharing.",
canonicalUrl: "Add canonical URL to prevent duplicate content issues.",
robotsTags: "If this page should be indexed, remove noindex and nofollow values.",
viewportTag: "Add viewport meta tag for mobile compatibility.",
langAttribute: "Add HTML lang attribute for accessibility and SEO.",
nextSeo: {
title: "Using next-seo",
description: "The next-seo package simplifies SEO management in Next.js projects. Using this package, you can manage all meta tags centrally."
},
dynamicMetaTags: {
title: "Dynamic Meta Tags",
description: "For pages with dynamic content, create dynamic meta tags based on page content. This helps search engines better understand your page."
},
structuredData: {
title: "Structured Data",
description: "Add structured data in JSON-LD format. This enables rich snippets to be displayed in search results."
},
hreflang: {
title: "Hreflang Tags",
description: "Add hreflang tags for multilingual sites. This helps search engines show the correct language version of the page."
}
}
},
semanticHtml: {
title: "Semantic HTML Issues",
noIssues: "No semantic HTML issues detected. Great!",
issues: {
multipleH1: "Multiple H1 tags used",
h2BeforeH1: "H2 tag used before H1",
h3BeforeH2: "H3 tag used before H2",
noSemanticTags: "No semantic HTML tags used",
imgWithoutAlt: "Missing alt attribute in image tags",
genericLinkText: "Generic link texts used"
},
recommendations: {
title: "Semantic HTML Recommendations",
headingHierarchy: "Use proper heading hierarchy. H1 tag should be at the top of the page.",
h3AfterH2: "Use proper heading hierarchy. H3 tags should come after H2 tags.",
useSemanticTags: "Use semantic HTML5 tags (header, nav, main, article, section, aside, footer) instead of div and span.",
addAltAttributes: "Add alt attribute to all image tags. This is important for accessibility and SEO.",
descriptiveLinkText: "Use more descriptive link texts instead of generic ones like \"here\", \"click\", \"link\", \"read more\".",
semanticHtml: {
title: "Using Semantic HTML",
description: "Semantic HTML tags better define the structure of your page and help search engines better understand your content."
},
headings: {
title: "Heading Hierarchy",
description: "Use proper heading hierarchy. Each page should have one H1 tag and other headings should be hierarchically ordered."
},
altAttributes: {
title: "Alt Attribute",
description: "Add alt attribute to all image tags. This provides a text alternative for visual content and is important for accessibility."
},
linkTexts: {
title: "Descriptive Link Texts",
description: "Link texts should clearly indicate where the link goes. Use more descriptive texts instead of generic ones like \"here\", \"click\"."
}
}
},
accessibility: {
title: "Accessibility Issues",
noIssues: "No accessibility issues detected. Great!",
issues: {
ariaAttributesMissing: "Missing ARIA attributes",
formLabelsMissing: "Missing labels for form inputs",
lowContrast: "Low contrast ratio",
keyboardNavigationMissing: "Missing keyboard navigation",
negativeTabIndex: "Using tabIndex=\"-1\""
},
recommendations: {
title: "Accessibility Recommendations",
addAriaAttributes: "Add ARIA attributes and roles for accessibility.",
addFormLabels: "Add labels for all form inputs and connect them to inputs with the for attribute.",
improveContrast: "Ensure sufficient contrast ratio between text and background. According to WCAG 2.1 AA standard, there should be at least 4.5:1 contrast ratio for normal text and at least 3:1 for large text.",
addKeyboardNavigation: "Add keyboard events for onClick events. This improves accessibility for keyboard users.",
avoidNegativeTabIndex: "Using tabIndex=\"-1\" removes the element from keyboard navigation. This can cause accessibility issues.",
ariaAttributes: {
title: "ARIA Attributes",
description: "ARIA attributes improve the accessibility of your web page. These attributes help screen readers better understand your content."
},
formLabels: {
title: "Form Labels",
description: "Add labels for all form inputs. This helps users understand what the inputs are for."
},
contrast: {
title: "Contrast Ratio",
description: "Ensure sufficient contrast ratio between text and background. This is important for users with visual impairments."
},
keyboardNavigation: {
title: "Keyboard Navigation",
description: "Ensure all interactive elements are accessible via keyboard. This is important for users who cannot use a mouse."
},
accessibilityTests: {
title: "Accessibility Tests",
description: "Regularly test your application for accessibility. You can use tools like axe, Lighthouse."
}
}
},
visualize: {
title: "SEO Analysis",
summary: "Summary",
totalIssues: "Total {totalIssues} SEO issues detected:",
metaTagIssues: "Meta Tag Issues",
semanticHtmlIssues: "Semantic HTML Issues",
accessibilityIssues: "Accessibility Issues",
detectedIssues: "Detected Issues",
file: "File",
issue: "Issue",
recommendation: "Recommendation",
recommendations: "Recommendations"
}
},
"data-fetching": {
name: "data-fetching",
description: "Analyzes data fetching methods and strategies",
recommendations: {
serverSideProps: {
withRevalidate: "Consider using getStaticProps instead of getServerSideProps with revalidate",
withRequestData: "getServerSideProps is a good choice since you need request information",
default: "If data doesn't change frequently, consider using getStaticProps + revalidate (ISR)"
},
staticProps: {
noRevalidate: "If data can change, use ISR (Incremental Static Regeneration) by adding revalidate",
lowRevalidate: "Revalidate value is too low. Consider using a higher value to prevent unnecessary regenerations",
default: "getStaticProps + revalidate (ISR) is a good choice"
},
staticPaths: {
fallbackFalse: "fallback: false returns 404 for unknown paths. If new content is added, consider using fallback: \"blocking\" or fallback: true",
fallbackBlocking: "fallback: \"blocking\" is a good choice. It behaves like SSR for unknown paths",
fallbackTrue: "With fallback: true, don't forget to show a loading state",
default: "Specify fallback value for getStaticPaths"
},
swr: {
noRevalidateOnFocus: "Specify options like revalidateOnFocus, revalidateOnReconnect",
noDedupingInterval: "Add dedupingInterval to prevent unnecessary requests",
default: "SWR is a good choice for client-side data fetching"
},
reactQuery: {
noStaleTime: "Specify staleTime and cacheTime values",
zeroStaleTime: "staleTime: 0 fetches new data on every render. Consider using a higher value to prevent unnecessary requests",
default: "React Query is a good choice for client-side data fetching"
},
fetch: {
noCache: "Add cache strategy to fetch request: { cache: \"force-cache\" } or { cache: \"no-store\" }",
forceCache: "force-cache is a good choice for static data",
noStore: "no-store is a good choice for dynamic data",
default: "Choose appropriate cache strategy for fetch API"
},
axios: {
default: "Consider using axios-cache-adapter to add caching mechanism for Axios"
}
},
issues: {
bothDataFetchingMethods: {
issue: "Using both getServerSideProps and getStaticProps in the same file",
recommendation: "Instead of using these two functions in the same file, separate them into different files"
},
staticPropsNoRevalidate: {
issue: "Using getStaticProps without specifying revalidate",
recommendation: "Add revalidate for ISR (Incremental Static Regeneration)"
},
fetchNoCache: {
issue: "Using fetch API without specifying cache strategy",
recommendation: "Add cache strategy to fetch request: { cache: \"force-cache\" } or { cache: \"no-store\" }"
}
},
generalRecommendations: {
appRouter: {
title: "Data Fetching with App Router",
description: "If you're using App Router, you can fetch data with React Server Components. This reduces client-side JavaScript and improves SEO."
},
clientSide: {
title: "Using SWR or React Query",
description: "Use SWR or React Query for client-side data fetching. These libraries automatically provide features like caching, revalidation, error handling."
},
isr: {
title: "Incremental Static Regeneration (ISR)",
description: "Use ISR with getStaticProps for data that doesn't change frequently. This allows static pages to be regenerated at specific intervals."
}
},
visualize: {
title: "Data Fetching Analysis",
methods: {
title: "Data Fetching Methods",
serverSideProps: "getServerSideProps",
staticProps: "getStaticProps",
staticPaths: "getStaticPaths",
revalidate: "Revalidate",
fallback: "Fallback",
notSpecified: "Not Specified",
recommendation: "Recommendation"
},
clientSide: {
title: "Client-side Data Fetching",
swr: "SWR",
reactQuery: "React Query",
fetch: "Fetch API",
axios: "Axios",
revalidateOnFocus: "revalidateOnFocus",
staleTime: "staleTime",
cache: "Cache"
},
cacheStrategies: {
title: "Cache Strategies",
issues: {
title: "Detected Issues",
noIssues: "No issues detected. Great!",
issue: "Issue"
},
recommendations: {
title: "General Recommendations"
}
}
}
},
"code-quality": {
name: "code-quality",
description: "Checks code quality and best practices",
types: {
"unused-component": "Unused Component"
},
visualize: {
title: "Unused Components",
noUnusedComponents: "No unused components found."
}
},
routing: {
name: "routing",
description: "Analyzes and visualizes route structure",
visualize: {
title: "Route Analysis",
noRoutes: "No routes found.",
appRouter: "App Router",
pagesRouter: "Pages Router",
pages: "Pages",
apiRoutes: "API Routes",
staticPages: "Static Pages",
dynamicPages: "Dynamic Pages",
staticApiRoutes: "Static API Routes",
dynamicApiRoutes: "Dynamic API Routes",
parameters: "Parameters"
}
},
history: {
name: "history",
description: "Analyzes project history and changes",
error: {
noGit: "Git repository not found. Git is required for historical analysis."
},
summary: {
title: "Summary",
totalCommits: "Total {totalCommits} commits examined, {analyzedCommits} commits analyzed.",
firstCommitDate: "First commit date: {date}",
lastCommitDate: "Last commit date: {date}"
},
commitHistory: {
title: "Commit History",
moreCommits: "... and {count} more commits"
},
metricChanges: {
title: "Metric Changes",
metrics: {
componentCount: "Total Component Count",
serverComponentCount: "Server Component Count",
clientComponentCount: "Client Component Count",
routeCount: "Total Route Count",
apiRouteCount: "API Route Count",
pageRouteCount: "Page Route Count",
dynamicRouteCount: "Dynamic Route Count",
staticRouteCount: "Static Route Count"
},
trend: "Trend",
firstValue: "First value",
lastValue: "Last value",
totalGrowth: "Total growth",
growthRate: "Growth rate",
perCommit: "/ commit",
changeDetails: "Change Details"
},
trends: {
rapidGrowth: "Rapid Growth",
steadyGrowth: "Steady Growth",
stable: "Stable",
steadyDecline: "Steady Decline",
rapidDecline: "Rapid Decline",
unknown: "Unknown"
},
visualize: {
title: "Change Over Time Analysis",
chartTitle: "{metricName} Change"
}
},
visualization: {
name: "visualization",
description: "Visualizes analysis results with interactive charts"
}
}
};