Skip to content
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

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open

Seo sitemap #422

wants to merge 3 commits into from

Conversation

luighis
Copy link

@luighis luighis commented Nov 27, 2024

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:

  • Introduce a comprehensive sitemap for various sections of the website, including blog, whitepaper, learn/security, and about pages, with appropriate change frequencies and priorities.

Enhancements:

  • Refactor sitemap generation functions to remove unnecessary parameters and streamline the process by using static parameters and updated data fetching methods.

Documentation:

  • Update metadata titles and descriptions for various pages to improve SEO and provide clearer information about the content.

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced sitemap functionality with additional entries for various routes, improving the structure and information provided.
    • Introduced new metadata generation for project pages, improving SEO and social sharing capabilities.
  • Improvements

    • Updated metadata titles and descriptions across several pages for better clarity and relevance.
    • Simplified function signatures across multiple sitemap functions, streamlining the code and improving performance.
    • Added changeFrequency property to sitemap entries for better search engine optimization.
  • Bug Fixes

    • Ensured proper handling of project content checks and redirects in the ProjectPage function.

Copy link

vercel bot commented Nov 27, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
bitlauncher ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 27, 2024 4:38am
smartsale-faucet ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 27, 2024 4:38am

Copy link
Contributor

sourcery-ai bot commented Nov 27, 2024

Reviewer's Guide by Sourcery

This 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 generation

classDiagram
    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"
Loading

Class diagram for updated metadata generation

classDiagram
    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"
Loading

File-Level Changes

Change Details Files
Refactored sitemap generation logic across routes
  • Removed dependency on language parameters in sitemap generation functions
  • Added changeFrequency field to sitemap entries
  • Updated priority values for different routes
  • Simplified sitemap generation by using generateStaticParams
  • Added new routes to the main sitemap (whitepaper, legal pages)
apps/web/app/(routes)/[lang]/sitemap.ts
apps/web/app/(routes)/[lang]/[project]/sitemap.ts
apps/web/app/(routes)/[lang]/[project]/auction/sitemap.ts
apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts
apps/web/app/(routes)/[lang]/blog/sitemap.ts
apps/web/app/sitemap.ts
Enhanced metadata and SEO descriptions across pages
  • Updated page titles to be more descriptive and SEO-friendly
  • Improved meta descriptions with more detailed content
  • Added dynamic metadata generation for project pages
  • Updated blog page SEO text source
apps/web/app/(routes)/[lang]/about/about-bitlauncher/page.tsx
apps/web/app/(routes)/[lang]/learn/security/page.tsx
apps/web/app/(routes)/[lang]/wallet/page.tsx
apps/web/app/(routes)/[lang]/whitepaper/page.tsx
apps/web/app/(routes)/[lang]/blog/page.tsx
apps/web/app/(routes)/[lang]/[project]/page.tsx
apps/web/app/(routes)/[lang]/[project]/presale/page.tsx
Improved blog article sitemap handling
  • Switched to using getAllArticles service for article sitemap generation
  • Added proper lastModified dates using article publish dates
  • Simplified article URL generation logic
apps/web/app/(routes)/[lang]/blog/[category]/[slug]/sitemap.ts
apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

coderabbitai bot commented Nov 27, 2024

Walkthrough

The pull request introduces significant modifications across multiple files, primarily focusing on the sitemap functions and the addition of generateMetadata functions for improved metadata handling. The changes simplify function signatures by removing unnecessary parameters and enhance the logic for generating URLs and project metadata. Additionally, metadata for various pages has been updated to provide clearer and more specific descriptions and titles, improving the overall structure and functionality of the application.

Changes

File Path Change Summary
apps/web/app/(routes)/[lang]/[project]/auction/sitemap.ts Updated sitemap function signature to remove params, streamlined project retrieval and URL mapping, added changeFrequency.
apps/web/app/(routes)/[lang]/[project]/page.tsx Added generateMetadata function for project metadata retrieval, modified ProjectPage for content checks.
apps/web/app/(routes)/[lang]/[project]/presale/page.tsx Introduced generateMetadata for project metadata, maintained existing ProjectPage logic.
apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts Updated sitemap function to remove params, streamlined project retrieval and URL mapping, added changeFrequency.
apps/web/app/(routes)/[lang]/[project]/sitemap.ts Modified sitemap function to remove params, updated URL mapping to reflect new data structure.
apps/web/app/(routes)/[lang]/about/about-bitlauncher/page.tsx Updated metadata title and description for clarity and specificity.
apps/web/app/(routes)/[lang]/about/about-bitlauncher/sitemap.ts Updated sitemap function to remove params, simplified interface.
apps/web/app/(routes)/[lang]/blog/[category]/[slug]/sitemap.ts Changed sitemap function to remove props, now retrieves articles directly.
apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts Updated sitemap function to remove props, simplified URL generation.
apps/web/app/(routes)/[lang]/blog/page.tsx Modified generateMetadata function to change SEO text argument, added console log for debugging.
apps/web/app/(routes)/[lang]/blog/sitemap.ts Updated sitemap function to remove params, maintained internal logic.
apps/web/app/(routes)/[lang]/learn/security/page.tsx Updated metadata title and description for clarity.
apps/web/app/(routes)/[lang]/legal/privacy/page.tsx Updated metadata title for specificity.
apps/web/app/(routes)/[lang]/legal/terms/page.tsx Updated metadata title for specificity.
apps/web/app/(routes)/[lang]/sitemap.ts Removed params from sitemap function, expanded entries for various URLs with properties.
apps/web/app/(routes)/[lang]/wallet/page.tsx Updated metadata title and description for clarity, defined BalancesCard for wallet balance display.
apps/web/app/(routes)/[lang]/whitepaper/page.tsx Updated metadata title and description for clarity and detail.
apps/web/app/sitemap.ts Added new entries to the sitemap with associated properties.

Possibly related PRs

  • feat: support deposit addresses per chain #379: The changes in the sitemap function in apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts are directly related to the main PR as both involve significant modifications to the sitemap function, including the removal of the params argument and adjustments to how project data is accessed and structured.
  • fix(web: hotfixes v5 #405: The modifications in the sitemap function in apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts share a similar pattern of removing parameters and simplifying the function signature, aligning with the changes made in the main PR's sitemap function.
  • feat: ai assistant ui #411: While primarily focused on the layout.tsx file, the changes in the RootLayoutProps interface may indirectly relate to the overall structure and handling of parameters in the application, which is a theme present in the main PR's changes to the sitemap function.

🐰 "In the code where rabbits hop,
The sitemaps now take a new stop.
Metadata shines, clear and bright,
With titles that bring pure delight.
From auctions to wallets, all in a row,
Bitlauncher’s charm is sure to grow!" 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 0cb1b26 and 24cbe39.

📒 Files selected for processing (2)
  • apps/web/app/(routes)/[lang]/[project]/sitemap.ts (1 hunks)
  • apps/web/app/(routes)/[lang]/blog/page.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/app/(routes)/[lang]/[project]/sitemap.ts
  • apps/web/app/(routes)/[lang]/blog/page.tsx

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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a 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

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 keyword

The 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 date

Using 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:

  1. Add validation for NEXT_PUBLIC_APP_URL to prevent runtime errors
  2. 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

  1. Using process.env.NEXT_PUBLIC_APP_URL in static generation might cause issues if the environment variable is not available during build time.
  2. 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 handling

The 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 configurable

The 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 type
apps/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:

  1. Repeated URL base construction
  2. Nested mapping operations that could be simplified
  3. 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 debugging

The 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 dates

Currently, 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 solid

The 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 function

The sitemap generation logic could benefit from some improvements:

  1. Add validation for the NEXT_PUBLIC_APP_URL environment variable
  2. Consider extracting URL construction to a reusable utility function
  3. Consider making changeFrequency and priority configurable based on project requirements

Here'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 statement

Debug 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 centralization

Two suggestions for improvement:

  1. Add TypeScript type definition for the component:
-function BalancesCard() {
+function BalancesCard(): React.ReactElement {
  1. 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 handling

The 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 logic

The 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 dates

Using new Date() for all entries means they'll show the generation time rather than actual content modification times. Consider:

  1. Using specific dates for static content
  2. Fetching actual last modification dates for dynamic content (like blog)
- lastModified: new Date(),
+ lastModified: new Date('2024-01-01'), // Or fetch from content metadata

Also 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 queries

The 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 placeholder

The 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 operations

The 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 addressing

There 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 code

There'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

📥 Commits

Reviewing files that changed from the base of the PR and between 9969a0c and 0cb1b26.

📒 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 with AVAILABLE_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:

  1. The NEXT_PUBLIC_ prefix indicates it's intentionally exposed to the client-side, which is correct for URL construction in sitemap generation
  2. The variable is used consistently across multiple sitemap files in a standardized way
  3. The monorepo structure shows proper environment configuration management through the app-env package
  4. 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:

  1. The sitemap is properly generated as XML in production
  2. The sitemap is registered in robots.txt
  3. 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:

  1. Sitemap is correctly registered in robots.txt with Sitemap: https://bitlauncher.ai/sitemap.xml
  2. Next.js dynamic sitemap generation is properly implemented using the MetadataRoute API
  3. Multiple sitemap files exist for different sections, following a modular approach
  4. 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:

  1. Uses the standard Next.js environment variable pattern
  2. Is properly prefixed for client exposure
  3. 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.

apps/web/app/(routes)/[lang]/[project]/sitemap.ts Outdated Show resolved Hide resolved
@@ -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')
Copy link
Contributor

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

Comment on lines +46 to +48
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',
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 27, 2024

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

Copy link
Contributor

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

Copy link
Contributor

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.

Comment on lines +174 to +181
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,
}
}
Copy link
Contributor

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:

  1. Add error handling for async operations
  2. 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.

Suggested change
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',
}
}
}

Copy link
Contributor

@AndlerRL AndlerRL left a 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants