-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seo sitemap #422
base: develop
Are you sure you want to change the base?
Seo sitemap #422
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Reviewer's Guide by SourceryThis PR implements SEO improvements across the application by updating the sitemap generation and metadata for various pages. The changes include refactoring sitemap generation to be more efficient, adding change frequencies and priorities for different routes, and improving page metadata with more descriptive titles and descriptions. Class diagram for updated sitemap generationclassDiagram
class Sitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class BlogSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class AuctionSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class ProjectSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class PresaleSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class AboutBitlauncherSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class SecuritySitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class WhitepaperSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
class LegalSitemap {
+sitemap() Promise<MetadataRoute.Sitemap>
}
Sitemap <|-- BlogSitemap
Sitemap <|-- AuctionSitemap
Sitemap <|-- ProjectSitemap
Sitemap <|-- PresaleSitemap
Sitemap <|-- AboutBitlauncherSitemap
Sitemap <|-- SecuritySitemap
Sitemap <|-- WhitepaperSitemap
Sitemap <|-- LegalSitemap
note for Sitemap "Refactored to remove parameters and use static data"
note for BlogSitemap "Uses getAllArticles service"
note for AuctionSitemap "Uses generateStaticParams service"
note for ProjectSitemap "Uses generateStaticParams service"
note for PresaleSitemap "Uses generateStaticParams service"
Class diagram for updated metadata generationclassDiagram
class ProjectPage {
+generateMetadata(params: ProjectPageProps) Metadata
}
class PresalePage {
+generateMetadata(params: ProjectPageProps) Metadata
}
class BlogPage {
+generateMetadata(params: BlogPageProps) Metadata
}
ProjectPage <|-- PresalePage
ProjectPage <|-- BlogPage
note for ProjectPage "Generates metadata using project details"
note for PresalePage "Generates metadata with presale-specific details"
note for BlogPage "Generates metadata using page SEO text"
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
WalkthroughThe pull request introduces significant modifications across multiple files, primarily focusing on the Changes
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @luighis - I've reviewed your changes - here's some feedback:
Overall Comments:
- Remove the console.log statement in blog/page.tsx as it appears to be debug code
- The terms page metadata incorrectly shows 'Privacy Policy' as the title - this should be updated to 'Terms of Service' or similar
Here's what I looked at during the review
- 🟢 General issues: all looks good
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
🧹 Outside diff range and nitpick comments (23)
apps/web/app/(routes)/[lang]/whitepaper/page.tsx (1)
13-14
: LGTM! SEO-friendly metadata updates.The metadata changes improve SEO by providing more descriptive and comprehensive content. The title and description are well-crafted and align with SEO best practices.
Consider adding more metadata properties to further enhance SEO:
export const metadata: Metadata = { title: 'Comprehensive Whitepaper', description: 'Explore the detailed whitepaper of Bitlauncher, covering all aspects of our innovative platform and technology.', + openGraph: { + title: 'Comprehensive Whitepaper | Bitlauncher', + description: 'Explore the detailed whitepaper of Bitlauncher, covering all aspects of our innovative platform and technology.', + type: 'article', + }, + twitter: { + card: 'summary_large_image', + title: 'Comprehensive Whitepaper | Bitlauncher', + description: 'Explore the detailed whitepaper of Bitlauncher, covering all aspects of our innovative platform and technology.', + } }apps/web/app/(routes)/[lang]/blog/sitemap.ts (2)
4-4
: Consider removing async keywordThe function is marked as async but doesn't contain any asynchronous operations. Consider removing the async keyword since it adds unnecessary Promise wrapping.
-export default async function sitemap(): Promise<MetadataRoute.Sitemap> { +export default function sitemap(): MetadataRoute.Sitemap {
Line range hint
5-20
: Consider using a static lastModified dateUsing
new Date()
for lastModified will generate a different timestamp on each request, which could impact caching efficiency. Consider using a static date that represents when the blog content was last updated.{ url: `https://${process.env.NEXT_PUBLIC_APP_URL}/blog`, - lastModified: new Date(), + lastModified: new Date('2024-01-01'), // Update this when blog content changes priority: 0.9,apps/web/app/(routes)/[lang]/about/about-bitlauncher/sitemap.ts (1)
Line range hint
7-9
: Validate environment variable and consider static lastModified date.Two suggestions for improvement:
- Add validation for
NEXT_PUBLIC_APP_URL
to prevent runtime errors- Consider using a static lastModified date that reflects actual content updates instead of the current date
Apply this diff:
+if (!process.env.NEXT_PUBLIC_APP_URL) { + throw new Error('NEXT_PUBLIC_APP_URL environment variable is not defined'); +} + +// Use a static date that reflects the last content update +const LAST_MODIFIED = new Date('2024-01-01'); + return [ { url: `https://${process.env.NEXT_PUBLIC_APP_URL}/about/about-bitlauncher`, - lastModified: new Date(), + lastModified: LAST_MODIFIED, priority: 0.6,apps/web/app/(routes)/[lang]/[project]/sitemap.ts (2)
Line range hint
8-22
: Consider environment variable handling and URL security
- Using
process.env.NEXT_PUBLIC_APP_URL
in static generation might cause issues if the environment variable is not available during build time.- The URL construction should include input validation for
item.project
to prevent potential security issues.Consider adding validation and fallback:
+ const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'example.com' + const safeProjectId = encodeURIComponent(item.project) - url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${item.project}`, + url: `https://${baseUrl}/${safeProjectId}`,
13-20
: Enhance language alternate handlingThe current implementation of language alternates is good, but consider adding hreflang annotations in your page metadata as well for better SEO.
Consider adding a helper function for consistent URL generation across the application:
function generateLocalizedUrl(lang: string, project: string, baseUrl: string) { const safeProject = encodeURIComponent(project); return `https://${baseUrl}/${lang}/${safeProject}`; }apps/web/app/(routes)/[lang]/[project]/auction/sitemap.ts (1)
11-11
: Consider making changeFrequency configurableThe hardcoded 'yearly' change frequency might not be suitable for all auction pages. Consider making this configurable based on the project type or auction status.
- changeFrequency: 'yearly', + changeFrequency: getChangeFrequency(item.project), // Add a function to determine frequency based on project typeapps/web/app/(routes)/[lang]/blog/[category]/[slug]/sitemap.ts (1)
9-23
: Optimize URL generation and improve code maintainability.The current implementation has several areas for improvement:
- Repeated URL base construction
- Nested mapping operations that could be simplified
- Direct environment variable usage
Consider refactoring to this more maintainable structure:
+const BASE_URL = `https://${process.env.NEXT_PUBLIC_APP_URL}` + +const createArticleUrl = (lang: string, category: string, slug: string) => + `${BASE_URL}${lang ? `/${lang}` : ''}/blog/${category}/${slug}` + export default async function sitemap(): Promise<MetadataRoute.Sitemap> { const articles = await getAllArticles() if (!articles) return [] return articles.flatMap((item) => item.articles.map((article) => ({ - url: `https://${process.env.NEXT_PUBLIC_APP_URL}/blog/${item.category}/${article.slug}`, + url: createArticleUrl('', item.category, article.slug), lastModified: article._publishedAt, priority: 0.6, alternates: { languages: Object.fromEntries( AVAILABLE_LANGS.map((lang) => [ lang, - `https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/blog/${item.category}/${article.slug}`, + createArticleUrl(lang, item.category, article.slug), ]), ), }, })), ) }apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts (3)
7-11
: Add error logging for better debuggingThe current error handling silently returns an empty array, which could hide potential issues. Consider adding error logging for better observability.
try { sections = await getArticleSections('en') } catch (error) { + console.error('Failed to fetch article sections:', error) return [] }
Line range hint
15-26
: Consider using actual content update datesCurrently,
lastModified
uses the current date, which might not reflect when the content was last updated. Consider using the actual last modification date from the article sections data.return categories.map((category) => ({ url: `https://${process.env.NEXT_PUBLIC_APP_URL}/blog/${category}`, - lastModified: new Date(), + lastModified: section.updatedAt || new Date(), priority: 0.7, alternates: {
Line range hint
1-26
: SEO structure looks solidThe sitemap implementation follows SEO best practices:
- Proper URL structure
- Language alternates support
- Reasonable priority values
- Error resilience
Consider adding
changefreq
to provide search engines with more crawling guidance.apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts (1)
11-24
: Consider adding environment variable validation and URL utility functionThe sitemap generation logic could benefit from some improvements:
- Add validation for the
NEXT_PUBLIC_APP_URL
environment variable- Consider extracting URL construction to a reusable utility function
- Consider making
changeFrequency
andpriority
configurable based on project requirementsHere's a suggested refactor:
+ const validateAppUrl = (url: string | undefined): string => { + if (!url) throw new Error('NEXT_PUBLIC_APP_URL is not defined'); + return url; + } + + const generateProjectUrl = (appUrl: string, lang: string, project: string, path: string) => + `https://${appUrl}/${lang}/${project}/${path}`; export default async function sitemap(): Promise<MetadataRoute.Sitemap> { const projects = await generateStaticParams() + const appUrl = validateAppUrl(process.env.NEXT_PUBLIC_APP_URL); return projects.map((item) => ({ - url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${item.project}/presale`, + url: generateProjectUrl(appUrl, '', item.project, 'presale'), lastModified: new Date(), changeFrequency: 'yearly', priority: 0.9, alternates: { languages: Object.fromEntries( AVAILABLE_LANGS.map((lang) => [ lang, - `https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${item.project}/presale`, + generateProjectUrl(appUrl, lang, item.project, 'presale'), ]), ), }, })) }apps/web/app/sitemap.ts (1)
29-46
: Consider enhancing sitemap entries with dynamic lastModified dates.Instead of using
new Date()
which sets the modification date to when the sitemap is generated, consider tracking actual content updates for more accurate lastModified dates. This helps search engines better understand your content freshness.Example implementation:
import { getFileLastModifiedDate } from '../utils/file-utils' // Inside sitemap function { url: 'https://bitlauncher.ai/whitepaper', lastModified: await getFileLastModifiedDate('whitepaper'), changeFrequency: 'monthly', priority: 0.7, }apps/web/app/(routes)/[lang]/blog/page.tsx (1)
37-37
: Remove debug console.log statementDebug logging statements should be removed before deployment to production.
- console.log("🚀 ~ pageSeo:", pageSeo)
apps/web/app/(routes)/[lang]/wallet/page.tsx (1)
Line range hint
52-67
: Consider TypeScript improvements and text centralizationTwo suggestions for improvement:
- Add TypeScript type definition for the component:
-function BalancesCard() { +function BalancesCard(): React.ReactElement {
- Consider centralizing the description text to avoid duplication with metadata:
+const WALLET_DESCRIPTIONS = { + title: 'Wallet Balances', + description: 'Your balances on the Bitcash | Bitlauncher ecosystem. Connect your Bitcash and EVM wallets' +} as const; export const metadata: Metadata = { - title: 'Wallet Balances', - description: - 'Your balances on the Bitcash | Bitlauncher ecosystem. Connect your Bitcash and EVM wallets', + title: WALLET_DESCRIPTIONS.title, + description: WALLET_DESCRIPTIONS.description, } function BalancesCard(): React.ReactElement { return ( <Card> <CardHeader> - <CardTitle>Wallet Balances</CardTitle> + <CardTitle>{WALLET_DESCRIPTIONS.title}</CardTitle> <CardDescription> - Your balances on the Bitcash | Bitlauncher ecosystem. Connect your - Bitcash and EVM wallets. + {WALLET_DESCRIPTIONS.description} </CardDescription> </CardHeader>apps/web/app/(routes)/[lang]/about/about-bitlauncher/page.tsx (1)
Line range hint
11-16
: Fix inconsistent language handlingThe component receives a dynamic language parameter but passes a hardcoded 'en' to the child component. This breaks internationalization support and ignores the user's language preference.
Apply this fix:
<AboutBitlauncherPageLanding content={content} params={{ - lang: 'en', + lang: params.lang, }} />apps/web/app/(routes)/[lang]/sitemap.ts (2)
21-76
: Consider extracting common URL construction logicThe sitemap entries follow a consistent pattern but contain duplicated code. Consider refactoring to improve maintainability.
+ const createSitemapEntry = ( + path: string, + changeFrequency: 'yearly' | 'monthly', + priority: number + ) => ({ + url: `https://${process.env.NEXT_PUBLIC_APP_URL}${path}`, + lastModified: new Date(), + changeFrequency, + priority, + alternates: { + languages: Object.fromEntries( + AVAILABLE_LANGS.map((lang) => [ + lang, + `https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}${path}`, + ]), + ), + }, + }); export default async function sitemap(): Promise<MetadataRoute.Sitemap> { return [ - { - url: `https://${process.env.NEXT_PUBLIC_APP_URL}`, - lastModified: new Date(), - changeFrequency: 'yearly', - priority: 1, - alternates: { - languages: Object.fromEntries( - AVAILABLE_LANGS.map((lang) => [ - lang, - `https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}`, - ]), - ), - }, - }, + createSitemapEntry('', 'yearly', 1), + createSitemapEntry('/blog', 'monthly', 0.8), + createSitemapEntry('/whitepaper', 'yearly', 0.6), + createSitemapEntry('/learn/security', 'yearly', 0.6), + createSitemapEntry('/about/about-bitlauncher', 'yearly', 0.6), ]; }
23-23
: Consider using specific lastModified datesUsing
new Date()
for all entries means they'll show the generation time rather than actual content modification times. Consider:
- Using specific dates for static content
- Fetching actual last modification dates for dynamic content (like blog)
- lastModified: new Date(), + lastModified: new Date('2024-01-01'), // Or fetch from content metadataAlso applies to: 37-37, 51-51, 65-65
apps/web/app/(routes)/[lang]/[project]/presale/page.tsx (2)
Line range hint
29-30
: Consider optimizing the database queriesThe TODO comment indicates that multiple separate queries could be optimized into a single query. This could improve page load performance.
Would you like me to help create a more efficient query that combines these operations?
Line range hint
39-39
: Implement auction logic or remove placeholderThe code contains a hardcoded
false
value with a TODO comment about implementing auction logic. This could lead to confusion about the actual state of the auction.Would you like me to help implement the auction logic or create a GitHub issue to track this task?
apps/web/app/(routes)/[lang]/[project]/page.tsx (3)
Line range hint
18-22
: Add error handling for async operationsThe component performs multiple async operations (
getDictionary
,getProjectBySlug
,createSupabaseServerClient
,getPresaleData
) without proper error handling. Consider wrapping these in try-catch blocks to gracefully handle potential failures.- const dict = await getDictionary(params.lang) - const project = await getProjectBySlug(params.project, dict) - if (!project || !project.content) redirect('/') + try { + const dict = await getDictionary(params.lang) + const project = await getProjectBySlug(params.project, dict) + if (!project || !project.content) redirect('/') + } catch (error) { + console.error('Failed to fetch project data:', error) + redirect('/') + }
Line range hint
25-28
: TODO comments need addressingThere are multiple TODOs related to auction logic. These placeholders could lead to unexpected behavior.
Would you like me to help create a GitHub issue to track the implementation of the auction logic? This should include:
- Implementing auction status check
- Setting actual auction start/end dates
- Adding auction data fetching similar to presale
Line range hint
103-112
: Remove or implement commented codeThere's a commented-out code block that appears to be an alternative implementation for rendering content. This should either be implemented or removed to maintain code clarity.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (18)
apps/web/app/(routes)/[lang]/[project]/auction/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/[project]/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/[project]/presale/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/[project]/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/about/about-bitlauncher/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/about/about-bitlauncher/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/blog/[category]/[slug]/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/blog/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/blog/sitemap.ts
(1 hunks)apps/web/app/(routes)/[lang]/learn/security/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/legal/privacy/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/legal/terms/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/sitemap.ts
(2 hunks)apps/web/app/(routes)/[lang]/wallet/page.tsx
(1 hunks)apps/web/app/(routes)/[lang]/whitepaper/page.tsx
(1 hunks)apps/web/app/sitemap.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/app/(routes)/[lang]/legal/terms/page.tsx
🔇 Additional comments (22)
apps/web/app/(routes)/[lang]/about/about-bitlauncher/sitemap.ts (2)
4-4
: LGTM! Function signature simplified.
The removal of the unused params
parameter simplifies the interface while maintaining the same functionality.
Line range hint 10-17
: Verify language alternates configuration.
The language alternates implementation looks correct, but let's verify the configuration across other routes for consistency.
✅ Verification successful
The previous search might have failed because the pattern was too specific. Let's examine the actual content of the sitemap files to verify the language alternates implementation and URL structure consistency.
Language alternates configuration is consistent across routes
After reviewing all sitemap files, the language alternates implementation is consistent across the codebase:
- All routes correctly import and use
AVAILABLE_LANGS
from@/lib/config
- The URL structure consistently follows the pattern
https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/[route]
- All implementations use
Object.fromEntries
withAVAILABLE_LANGS.map()
to generate the language alternates - The only exception is the root
sitemap.ts
which intentionally doesn't include alternates as it serves as the base sitemap
Note: There is one minor inconsistency in legal/terms/sitemap.ts
where the URL uses learn/terms
instead of legal/terms
in the alternates, but this is outside the scope of the current review.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check language alternates implementation across sitemap files
# Expected: Similar pattern using AVAILABLE_LANGS and consistent URL structure
# Find all sitemap.ts files
echo "Checking sitemap implementations across routes..."
rg -l 'sitemap.*MetadataRoute.Sitemap' --type ts
# Check for language alternates implementation
echo "\nChecking language alternates implementation..."
rg -A 5 'alternates.*languages.*Object.fromEntries' --type ts
Length of output: 788
Script:
#!/bin/bash
# Let's try a different approach to check language alternates implementation
# Search for alternates configuration in sitemap files
# First, let's check the content of sitemap files
for file in $(fd sitemap.ts); do
echo "=== Content of $file ==="
cat "$file"
echo -e "\n"
done
Length of output: 16218
apps/web/app/(routes)/[lang]/legal/privacy/page.tsx (1)
16-20
: Verify metadata consistency across pages.
Let's ensure this metadata structure aligns with other pages in the application.
apps/web/app/(routes)/[lang]/[project]/sitemap.ts (2)
5-5
: LGTM! Function signature simplified appropriately.
The removal of the unused params
parameter aligns with Next.js best practices for static sitemap generation.
6-6
: Verify the shape of data returned by generateStaticParams
Ensure that generateStaticParams()
consistently returns objects with the expected project
property.
✅ Verification successful
Based on the comprehensive analysis of the codebase, I can now generate the final response:
The shape of data returned by generateStaticParams is consistent and well-defined
The implementation in [project]/page.tsx
shows that generateStaticParams()
returns an array of objects with the expected shape { lang, project }
. This is consistently used across sitemap generation in multiple files, including presale and auction routes. The data comes from a well-structured projects array defined in the codebase that ensures data consistency.
Key validations:
- The project data is strongly typed with
ProjectPageParams
interface - The function properly merges localized content with base project data
- The returned objects always contain the required
project
property - The implementation is used consistently across the application
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the shape of data returned by generateStaticParams
# Look for the implementation and usage of generateStaticParams
# Find the implementation
echo "Searching for generateStaticParams implementation:"
ast-grep --pattern 'export async function generateStaticParams() {
$$$
}'
# Find other usages to verify consistency
echo "Searching for other usages of item.project in sitemaps:"
rg -A 2 'item\.project.*sitemap'
Length of output: 801
Script:
#!/bin/bash
# Let's check the actual implementation in the sitemap.ts and page.ts files
# First, find the sitemap.ts file
echo "Searching for sitemap.ts implementation:"
fd "sitemap.ts" --exec cat {}
echo -e "\nSearching for page.ts implementation:"
fd "page.ts" --type f --exec sh -c 'echo "=== $1 ==="; cat "$1"' sh {}
# Look for any project-related types or interfaces
echo -e "\nSearching for project-related types:"
rg -A 5 "type.*Project|interface.*Project"
Length of output: 60113
Script:
#!/bin/bash
# Let's check the implementation of getProjects and getProjectBySlug to understand the data shape
echo "Searching for getProjects implementation:"
ast-grep --pattern 'export function getProjects($$$) {
$$$
}'
echo -e "\nSearching for getProjectBySlug implementation:"
ast-grep --pattern 'export function getProjectBySlug($$$) {
$$$
}'
# Also check the actual projects data
echo -e "\nSearching for project data in dictionaries:"
fd "projects.ts" --exec cat {}
Length of output: 95591
apps/web/app/(routes)/[lang]/[project]/auction/sitemap.ts (3)
1-5
: LGTM! Clean function signature simplification.
The removal of unused params
parameter and the addition of generateStaticParams
import improves code clarity.
6-6
: Verify the data structure from generateStaticParams
Let's ensure that the returned data structure contains the required project
field.
✅ Verification successful
Looking at the results, I can see that the generateStaticParams
function imported from '../page' (apps/web/app/(routes)/[lang]/[project]/page.tsx) returns an array of ProjectPageParams
which includes both lang
and project
fields. This is confirmed by the implementation:
export async function generateStaticParams(): Promise<ProjectPageParams[]> {
// ...
project.slug ? { lang, project: project.slug } : null,
The data structure is compatible with the sitemap usage since it returns objects containing the project
field that's used in the URL construction:
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${item.project}/auction`
Data structure compatibility verified
The generateStaticParams
function returns the expected data structure with the required project
field needed for sitemap generation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the structure of generateStaticParams implementation
# Expected: Should see a function that returns an array of objects with a 'project' field
# Search for the generateStaticParams implementation
ast-grep --pattern 'export async function generateStaticParams() {
$$$
}'
# Backup: If not found with exact match, search for any occurrence
rg -A 10 "generateStaticParams"
Length of output: 10317
8-22
: Verify environment variable availability in production
Ensure that NEXT_PUBLIC_APP_URL
is properly set in all deployment environments.
✅ Verification successful
The environment variable NEXT_PUBLIC_APP_URL is used consistently and safely
Based on the comprehensive analysis of the codebase, the usage of NEXT_PUBLIC_APP_URL
is appropriate and follows Next.js best practices:
- The
NEXT_PUBLIC_
prefix indicates it's intentionally exposed to the client-side, which is correct for URL construction in sitemap generation - The variable is used consistently across multiple sitemap files in a standardized way
- The monorepo structure shows proper environment configuration management through the app-env package
- The project documentation indicates proper environment setup for different deployment stages (prod, test, dev)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for environment variable usage in deployment configurations
# Expected: Should find environment variable definitions
# Search for environment variable definitions
rg "NEXT_PUBLIC_APP_URL" -g "*.env*"
rg "NEXT_PUBLIC_APP_URL" -g "*.yaml" -g "*.yml"
Length of output: 84
Script:
#!/bin/bash
# Let's check for the environment variable usage in a broader context
# including Next.js configuration files and deployment-related files
# Check for environment variable in various config files
rg "NEXT_PUBLIC_APP_URL"
# Also check for any URL construction patterns in the codebase
rg "process\.env\.NEXT_PUBLIC_APP_URL"
# Look for environment setup patterns in next config
fd "next.config" --exec cat {}
Length of output: 12443
Script:
#!/bin/bash
# Let's check for environment variable setup in deployment files and example env files
# Look for example env files or environment setup documentation
fd -g "*.env.example" --exec cat {}
fd -g "*.env.template" --exec cat {}
# Check for deployment configuration files
fd "deploy" -e yml -e yaml --exec cat {}
fd "deployment" -e yml -e yaml --exec cat {}
# Check for documentation about environment setup
fd "README" --exec cat {}
Length of output: 29500
apps/web/app/(routes)/[lang]/blog/[category]/[slug]/sitemap.ts (2)
1-3
: LGTM! Import statements are well-structured.
The imports are correctly organized and the new getAllArticles service aligns with the simplified sitemap generation approach.
12-13
: Verify the impact of priority value change.
The priority value has been increased from 0.5 to 0.6. While this is valid, ensure this aligns with your SEO strategy for blog articles relative to other pages.
✅ Verification successful
Let me gather more context about where these different priorities are used to better understand the SEO hierarchy.
Priority value of 0.6 for blog articles aligns with the site's SEO hierarchy
The priority value of 0.6 for blog articles is consistent with the site's SEO strategy, where:
- Main project pages and blog index have highest priority (0.9)
- Whitepaper and main blog section have high priority (0.8)
- Blog articles (0.6) are appropriately prioritized below main content but above utility pages like wallet (0.3)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check other sitemap priorities in the project
rg -g "sitemap.ts" "priority: \d+\.\d+" --no-filename | sort | uniq -c
Length of output: 269
Script:
#!/bin/bash
# Find all sitemap.ts files and show their paths along with priorities
rg -g "sitemap.ts" "priority: \d+\.\d+" -B 5 --with-filename
Length of output: 9864
apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts (1)
13-14
: LGTM!
The slug extraction is clean and straightforward.
apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts (2)
Line range hint 1-8
: LGTM! Clean function signature update
The removal of the params
parameter and switch to generateStaticParams()
aligns well with Next.js patterns and simplifies the function signature while maintaining proper typing.
9-9
: Verify the implementation of generateStaticParams
Let's ensure that the imported generateStaticParams
function properly returns the expected project data structure.
✅ Verification successful
Implementation of generateStaticParams is properly structured and type-safe
The function is well-implemented in the parent page.tsx:
- Returns Promise<ProjectPageParams[]>
- Properly handles localization by mapping through locales
- Uses getProjects() with dictionary support
- Includes null safety with type filtering
- The sitemap correctly uses the returned data to generate URLs with proper language alternates
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the implementation of generateStaticParams in the parent page.ts
# Check the implementation of generateStaticParams
ast-grep --pattern 'export async function generateStaticParams() {
$$$
}'
# Check the return type/structure
rg -A 10 "generateStaticParams" "../page.ts"
Length of output: 628
Script:
#!/bin/bash
# Let's try to find the correct path for the page.ts file and check its implementation
fd "page.ts" apps/web/app/\(routes\)/\[lang\]/\[project\]/presale/
# Check for any imports of generateStaticParams in the sitemap.ts
rg -A 5 "import.*generateStaticParams" apps/web/app/\(routes\)/\[lang\]/\[project\]/presale/sitemap.ts
# Look for the implementation in the project directory
ast-grep --pattern 'export async function generateStaticParams() {
$$$
}' --path apps/web/app/\(routes\)/\[lang\]/\[project\]
Length of output: 725
Script:
#!/bin/bash
# Let's check the implementation in the parent directory's page file
rg -A 10 "generateStaticParams" apps/web/app/\(routes\)/\[lang\]/\[project\]/page.tsx
# Also check the actual implementation using ast-grep
ast-grep --pattern 'export async function generateStaticParams() {
$$$
}' apps/web/app/\(routes\)/\[lang\]/\[project\]/page.tsx
# Let's also see how the data is used in sitemap.ts
rg -A 10 "projects.map" apps/web/app/\(routes\)/\[lang\]/\[project\]/presale/sitemap.ts
Length of output: 1259
apps/web/app/sitemap.ts (2)
29-46
: LGTM! Well-structured sitemap entries with appropriate priorities.
The new entries for whitepaper and legal pages are well-organized with consistent formatting and appropriate priority values that align with the existing hierarchy.
Line range hint 1-48
: Verify sitemap configuration and search engine registration.
Ensure that:
- The sitemap is properly generated as XML in production
- The sitemap is registered in robots.txt
- The sitemap is submitted to major search engines
✅ Verification successful
Based on the results from the shell scripts, I can now provide a final response:
Sitemap configuration is properly implemented with recommended practices.
The verification shows:
- Sitemap is correctly registered in robots.txt with
Sitemap: https://bitlauncher.ai/sitemap.xml
- Next.js dynamic sitemap generation is properly implemented using the MetadataRoute API
- Multiple sitemap files exist for different sections, following a modular approach
- The sitemap includes proper changeFrequency and priority settings
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if robots.txt exists and contains sitemap reference
fd -t f "robots.txt" -x cat {} | grep -i "sitemap"
# Check for next.js sitemap configuration in next.config.js
fd -t f "next.config.js" -x cat {} | grep -i "sitemap"
Length of output: 149
Script:
#!/bin/bash
# Check if there are any other sitemap-related files or configurations
fd -t f -e xml -e ts -e js -e json | grep -i "sitemap"
# Look for any sitemap-related code in the codebase
rg -i "sitemap" -g "!{node_modules,dist,build}/*" -A 2 -B 2
# Check package.json for sitemap-related dependencies
fd "package.json" -x cat {} | jq '.dependencies,.devDependencies' | grep -i "sitemap"
Length of output: 131987
apps/web/app/(routes)/[lang]/learn/security/page.tsx (1)
34-36
: SEO improvements look good, verify metadata length constraints.
The updated title and description are more descriptive and engaging, which should improve SEO performance. However, let's verify they meet search engine constraints:
- Title (55 chars): ✓ Within Google's 60-character limit
- Description (123 chars): ✓ Within Google's 155-160 character limit
✅ Verification successful
SEO metadata structure and length constraints are consistent across pages
The metadata changes for the security page align well with the site-wide SEO patterns:
- Title (55 chars) follows the same descriptive pattern seen in other pages like "About Bitlauncher" and "Whitepaper"
- Description (123 chars) maintains consistent length and style with other pages
- Both fields are well within Google's recommended limits (60 chars for title, 155-160 for description)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent metadata patterns across pages
# Look for other metadata exports to ensure consistent SEO structure
# Search for metadata exports in page components
rg -g '*.tsx' -g '*.ts' --multiline --multiline-dotall 'export const metadata: Metadata = \{.*?\}' -A 5
Length of output: 4399
apps/web/app/(routes)/[lang]/about/about-bitlauncher/page.tsx (1)
65-68
: LGTM! Well-structured metadata for SEO
The updated metadata follows SEO best practices with:
- Descriptive title that includes relevant keywords
- Clear and action-oriented description that explains the value proposition
apps/web/app/(routes)/[lang]/sitemap.ts (2)
4-4
: LGTM! Function signature simplified
The removal of the unused params
parameter improves code clarity while maintaining the same functionality.
Line range hint 9-19
: Verify environment variable availability
While the addition of changeFrequency
is good for SEO, let's ensure the environment variable is properly configured.
✅ Verification successful
Based on the gathered information, I can now provide the final response:
Environment variable setup follows Next.js best practices
The codebase follows proper environment variable handling through Vercel's deployment workflow:
- The README explicitly documents the setup process using
vercel env pull
NEXT_PUBLIC_APP_URL
is a public environment variable (prefixed with NEXT_PUBLIC_) as required for client-side usage- Environment variables are managed through Vercel's environment management system
The sitemap usage of this variable is safe as it:
- Uses the standard Next.js environment variable pattern
- Is properly prefixed for client exposure
- Has documented setup instructions
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if NEXT_PUBLIC_APP_URL is defined in environment files
echo "Checking for NEXT_PUBLIC_APP_URL in environment files..."
fd -t f -e env . | xargs grep "NEXT_PUBLIC_APP_URL"
Length of output: 174
Script:
#!/bin/bash
# Let's check for environment variable usage and configuration patterns
# First, check for any .env.example or similar template files
fd -t f -g '*.env*' .
# Then, let's look for the actual usage of this environment variable in the codebase
rg "NEXT_PUBLIC_APP_URL" -A 2 -B 2
# Also check package.json for any scripts or configuration that might set this variable
fd -t f -g 'package.json' . | xargs cat
Length of output: 32046
Script:
#!/bin/bash
# Let's check for Next.js configuration files that might contain environment variable setup
fd -t f -g 'next.config.*' apps/web/
# Also check for any documentation about environment setup
fd -t f -g 'README*' apps/web/
# And check for environment variable validation or configuration in the codebase
rg -A 3 -B 3 "env\.(NEXT_PUBLIC_APP_URL|validateEnv)" apps/web/
Length of output: 19862
Script:
#!/bin/bash
# Let's check the contents of next.config.js and README.md for environment setup instructions
echo "=== next.config.js contents ==="
cat apps/web/next.config.js
echo -e "\n=== README.md contents ==="
cat apps/web/README.md
# Also check for any environment validation in the codebase
rg -A 3 -B 3 "validateEnv|env\." apps/web/app/env.ts apps/web/app/config.ts apps/web/app/lib/env.ts 2>/dev/null
Length of output: 6231
apps/web/app/(routes)/[lang]/[project]/presale/page.tsx (1)
85-90
: Verify metadata implementation consistency
Let's ensure this metadata implementation pattern is consistent with other pages in the application.
✅ Verification successful
Metadata implementation is consistent across the application
The verification shows that the metadata implementation follows consistent patterns throughout the application:
- Project pages use dynamic metadata based on project data:
- Main project page uses project title and pitch
- Presale page uses project name with "Presale" prefix
- Other pages use static metadata with descriptive titles and descriptions
- Root layout (
[lang]/layout.tsx
) properly sets up metadata templates and defaults - Blog section correctly handles dynamic metadata from CMS data
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other generateMetadata implementations
ast-grep --pattern 'export async function generateMetadata({ params }: $_) {
$$$
}'
# Search for other metadata patterns
rg -A 5 'title:|description:' 'apps/web/app'
Length of output: 8960
apps/web/app/(routes)/[lang]/[project]/page.tsx (2)
Line range hint 147-166
: LGTM! Well-implemented static params generation
The implementation efficiently handles parallel processing of locales and properly filters out invalid params. The type safety is well maintained.
Line range hint 168-171
: LGTM! Well-implemented dynamic import
The dynamic import implementation follows Next.js best practices with proper loading state handling.
@@ -33,7 +33,8 @@ export default async function BlogPage({ params }: BlogPageProps) { | |||
export async function generateMetadata({ | |||
params, | |||
}: BlogPageProps): Promise<Metadata> { | |||
const pageSeo = await getPageSeoText('home') | |||
const pageSeo = await getPageSeoText('bitlauncher') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Based on the evidence gathered from the previous searches, I can now provide a final response:
The 'bitlauncher'
parameter appears incorrect for the blog page SEO
Looking at the usage patterns of getPageSeoText()
across the codebase:
- Blog category pages use the category name as the parameter
- The blog index page should use a consistent identifier for blog-related SEO content
- 'bitlauncher' is primarily used in product-specific contexts, not for the blog section
The parameter should likely be 'blog'
to maintain consistency with the page's purpose and context.
🔗 Analysis chain
Verify the correct page identifier for SEO text
The parameter 'bitlauncher'
seems inconsistent with this being a blog page. Should this perhaps be 'blog'
instead? This might affect the SEO content being retrieved.
Let me gather more information about the SEO text types and their usage.
Let me check the blog page structure and its SEO implementation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other getPageSeoText calls to understand the expected parameter values
rg "getPageSeoText\(" -A 1
Length of output: 871
Script:
#!/bin/bash
# Search for the type definition and any constants/enums related to page types
rg "CMSPageSeoText" -A 5
# Search for any configuration or constant files that might define valid page types
fd -e ts -e tsx -e json | xargs rg -l "bitlauncher|pageSeo|pageTypes"
Length of output: 13314
Script:
#!/bin/bash
# Check the blog page structure and its metadata implementation
ast-grep --pattern 'export default async function BlogPage' -A 10
# Check the implementation of getPageSeoText to understand the type parameter usage
ast-grep --pattern 'export async function getPageSeoText'
Length of output: 596
title: 'Wallet Balances', | ||
description: | ||
'Be part of the intelligent future and join the Ai/Web3 revolution now!', | ||
'Your balances on the Bitcash | Bitlauncher ecosystem. Connect your Bitcash and EVM wallets', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Based on the search results, I can now provide a definitive response about the branding format consistency:
Branding format shows inconsistency across the codebase
The separator format "Bitcash | Bitlauncher" is not consistently used across the codebase. Found multiple variations:
- "Bitcash | Bitlauncher" (with spaces)
- "Bitlauncher | Bitcash" (reversed order)
- "Bitlauncher/Bitcash" (with forward slash)
- "bitcash-bitlauncher" (with hyphen)
Specific locations that need attention:
apps/web/app/(routes)/[lang]/wallet/page.tsx
: Uses "Bitcash | Bitlauncher"apps/web/lib/projects.ts
: Uses "Bitlauncher | Bitcash" (reversed order)apps/web/components/routes/project/whitelist-address-button.tsx
: Uses "bitlauncher | bitcash" (lowercase)- Multiple dictionary files use "Bitlauncher/Bitcash" format
🔗 Analysis chain
Verify branding format consistency
The metadata description uses "Bitcash | Bitlauncher" format. Please ensure this separator format with spaces is consistent with brand guidelines across the application.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for different variations of brand name combinations to ensure consistency
rg -i "bitcash.*bitlauncher|bitlauncher.*bitcash" --type ts --type tsx
Length of output: 100
Script:
#!/bin/bash
# Search for different variations of brand name combinations using ripgrep
# Note: Using --type-add to properly handle TypeScript/TSX files
rg -i "bitcash.*bitlauncher|bitlauncher.*bitcash" --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' --type tsx --type ts
# Also search for metadata in other Next.js pages to check branding consistency
rg "title:|description:" --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' --type tsx --type ts -A 1 apps/web/app
Length of output: 64884
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai good finding! Are you sure those are the variants? Good providing the components having them. We have to update all of them to use Bitlauncher | Bitcash
. The lowercase variant might be due to logic reason.
cc - @luighis
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AndlerRL, I've re-verified the branding format variants across the codebase. The variants found are:
- "Bitcash | Bitlauncher" (used in
apps/web/app/(routes)/[lang]/wallet/page.tsx
) - "Bitlauncher | Bitcash" (used in
apps/web/lib/projects.ts
) - "Bitlauncher/Bitcash" (used in multiple dictionary files)
- "bitcash-bitlauncher" (used with hyphens)
I agree that updating all instances to use "Bitlauncher | Bitcash" will improve consistency across the codebase. The lowercase variant might indeed be due to logical reasons.
I've noted this for future reviews.
(^.^)/
🔗 Analysis chain
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Re-verify the branding format variants across the codebase
# Use ripgrep to search for different variations of 'Bitcash' and 'Bitlauncher' with different separators.
rg -i 'Bitcash\s*[|/-]\s*Bitlauncher|Bitlauncher\s*[|/-]\s*Bitcash' --type ts --type tsx
Length of output: 118
✏️ Learnings added
Learnt from: AndlerRL
PR: bitcashorg/smartsale#422
File: apps/web/app/(routes)/[lang]/wallet/page.tsx:46-48
Timestamp: 2024-11-28T07:28:44.332Z
Learning: The branding format should consistently be "Bitlauncher | Bitcash" throughout the codebase, including in metadata titles and descriptions.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
export async function generateMetadata({ params }: ProjectPageProps) { | ||
const dict = await getDictionary(params.lang) | ||
const project = await getProjectBySlug(params.project, dict) | ||
return { | ||
title: project?.title, | ||
description: project?.pitch, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance metadata implementation for better SEO
While the basic implementation is good, consider these improvements:
- Add error handling for async operations
- Include additional metadata fields for better SEO
export async function generateMetadata({ params }: ProjectPageProps) {
- const dict = await getDictionary(params.lang)
- const project = await getProjectBySlug(params.project, dict)
- return {
- title: project?.title,
- description: project?.pitch,
- }
+ try {
+ const dict = await getDictionary(params.lang)
+ const project = await getProjectBySlug(params.project, dict)
+
+ if (!project) {
+ return {
+ title: 'Project Not Found',
+ description: 'The requested project could not be found.',
+ }
+ }
+
+ return {
+ title: project.title,
+ description: project.pitch,
+ openGraph: {
+ title: project.title,
+ description: project.pitch,
+ type: 'website',
+ url: `/[lang]/${project.slug}`,
+ },
+ twitter: {
+ card: 'summary_large_image',
+ title: project.title,
+ description: project.pitch,
+ },
+ }
+ } catch (error) {
+ console.error('Failed to generate metadata:', error)
+ return {
+ title: 'Error',
+ description: 'Failed to load project details',
+ }
+ }
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export async function generateMetadata({ params }: ProjectPageProps) { | |
const dict = await getDictionary(params.lang) | |
const project = await getProjectBySlug(params.project, dict) | |
return { | |
title: project?.title, | |
description: project?.pitch, | |
} | |
} | |
export async function generateMetadata({ params }: ProjectPageProps) { | |
try { | |
const dict = await getDictionary(params.lang) | |
const project = await getProjectBySlug(params.project, dict) | |
if (!project) { | |
return { | |
title: 'Project Not Found', | |
description: 'The requested project could not be found.', | |
} | |
} | |
return { | |
title: project.title, | |
description: project.pitch, | |
openGraph: { | |
title: project.title, | |
description: project.pitch, | |
type: 'website', | |
url: `/[lang]/${project.slug}`, | |
}, | |
twitter: { | |
card: 'summary_large_image', | |
title: project.title, | |
description: project.pitch, | |
}, | |
} | |
} catch (error) { | |
console.error('Failed to generate metadata:', error) | |
return { | |
title: 'Error', | |
description: 'Failed to load project details', | |
} | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good changes! I noticed a few improvements that we can make. I added additional comments to the related feedbacks. all of them were given by coderabbitai. Next time make sure to review them (mark as resolved if a feedback doesn't apply) and make conversations to move forward.
Summary by Sourcery
Enhance the SEO capabilities of the website by implementing a detailed sitemap for multiple sections, improving metadata for better search engine visibility, and refactoring sitemap generation for efficiency.
New Features:
Enhancements:
Documentation:
Summary by CodeRabbit
Release Notes
New Features
Improvements
changeFrequency
property to sitemap entries for better search engine optimization.Bug Fixes