Skip to content

Templates engine#67

Merged
Stivenjs merged 4 commits into
mainfrom
templates-engine
Jun 5, 2025
Merged

Templates engine#67
Stivenjs merged 4 commits into
mainfrom
templates-engine

Conversation

@Stivenjs
Copy link
Copy Markdown
Contributor

@Stivenjs Stivenjs commented Jun 5, 2025

Summary by CodeRabbit

  • New Features

    • Added a store page that displays the store name from the URL or a message if the store is not found.
  • Bug Fixes

    • Improved handling of requests by validating hostnames and subdomains, ensuring correct redirection and URL rewriting based on the environment.
  • Refactor

    • Simplified middleware routing configuration for more efficient request matching and processing.

Stivenjs and others added 4 commits June 4, 2025 20:22
This commit updates the middleware to detect subdomains in both production and development environments. It implements URL rewriting to redirect users to the appropriate store page based on the detected subdomain, improving navigation and user experience. Additionally, the matcher configuration has been simplified to exclude specific paths, streamlining route handling.
… sanitization

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…logic

This commit refactors the middleware to enhance the subdomain extraction process and streamline URL rewriting based on detected subdomains. It introduces a dedicated function for subdomain extraction, improving code clarity and maintainability. Additionally, it updates the URL rewriting logic to handle root paths and ensure proper redirection for valid hostnames, enhancing user navigation.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2025

Walkthrough

This update introduces a new React component for handling dynamic store pages, displaying the store name or an error if not found. The middleware logic is refactored to validate hostnames, extract subdomains, and rewrite URLs accordingly, with a simplified matcher pattern for route protection and handling.

Changes

File(s) Change Summary
app/[store]/page.tsx Added new default exported React component StorePage to render store-specific content based on dynamic route parameter.
middleware.ts Refactored middleware to validate hostnames, extract subdomains, conditionally redirect or rewrite URLs, and simplified matcher pattern.

Poem

In the warren of code, a new store appears,
With middleware hopping through hosts and frontiers.
Subdomains now guide each bunny’s request,
While the store page displays its name with zest.
With paths rewritten and checks in the air,
The rabbit devs cheer—change handled with flair!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

Comment thread middleware.ts Dismissed
Copy link
Copy Markdown

@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: 2

🧹 Nitpick comments (4)
middleware.ts (2)

11-11: Consider adding null check for the host header.

While the fallback to empty string is good, you should also handle the case where the hostname might be invalid or malformed.

-  const hostname = request.headers.get('host') || ''
+  const hostname = request.headers.get('host') || ''
+  if (!hostname) {
+    console.error('Missing host header')
+    return NextResponse.next()
+  }

28-43: Simplify and improve subdomain extraction logic.

The subdomain extraction function could be simplified and made more robust.

-  const extractSubdomain = (hostname: string, isProduction: boolean): string => {
-    const cleanHostname = hostname.split(':')[0] // Remove port if present
-    const parts = cleanHostname.split('.')
-    if (isProduction) {
-      // En producción: verificar si hay un subdominio (ej: tienda.fasttify.com)
-      if (parts.length > 2 && cleanHostname.endsWith('fasttify.com')) {
-        return parts[0]
-      }
-    } else {
-      // En desarrollo: usar el formato subdominio.localhost:3000
-      if (parts.length > 1 && cleanHostname.endsWith('localhost')) {
-        return parts[0]
-      }
-    }
-    return ''
-  }
+  const extractSubdomain = (hostname: string): string => {
+    const cleanHostname = hostname.split(':')[0].toLowerCase()
+    const parts = cleanHostname.split('.')
+    
+    // Check for subdomain pattern
+    const expectedDomain = isProduction ? 'fasttify.com' : 'localhost'
+    const expectedParts = isProduction ? 3 : 2 // subdomain.fasttify.com vs subdomain.localhost
+    
+    if (parts.length >= expectedParts && cleanHostname.endsWith(expectedDomain)) {
+      const subdomain = parts[0]
+      // Return subdomain if it's not www
+      return subdomain === 'www' ? '' : subdomain
+    }
+    
+    return ''
+  }
app/[store]/page.tsx (2)

6-8: Simplify the store parameter extraction.

The double casting and undefined fallback is unnecessary since params.store will already be string | string[] | undefined.

-  const params = useParams()
-  const store = (params.store as string) || undefined
+  const params = useParams()
+  const store = params.store as string

9-11: Enhance the error message for better UX.

Consider providing a more helpful error message when the store is not found.

  if (!store) {
-    return <div>No se encontró la tienda</div>
+    return (
+      <div className="flex flex-col items-center justify-center min-h-screen">
+        <h1 className="text-2xl font-bold mb-4">Tienda no encontrada</h1>
+        <p className="text-gray-600">La tienda que buscas no existe o ha sido eliminada.</p>
+      </div>
+    )
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d59bda4 and a1e68ef.

📒 Files selected for processing (2)
  • app/[store]/page.tsx (1 hunks)
  • middleware.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Aplicar Prettier
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Ejecutar pruebas unitarias
🔇 Additional comments (4)
middleware.ts (3)

44-44: Fix the function call to match the updated signature.

The function call needs to be updated if you apply the suggested refactor above.


98-98: LGTM! The matcher simplification is appropriate.

The new matcher pattern correctly excludes API routes, static assets, images, and favicon while matching all other routes. This is cleaner than the previous explicit path list.


47-60:

Details

❌ Incorrect review comment

Consider adding subdomain validation.

The current implementation accepts any subdomain without validation. Consider adding a check to ensure the subdomain exists before rewriting URLs.

Consider adding validation like:

  if (subdomain && subdomain !== 'www') {
+    // TODO: Add validation to check if the store/subdomain exists
+    // This could prevent invalid subdomain access
    const url = request.nextUrl.clone()

🏁 Script executed:

#!/bin/bash
# Description: Check if there's any store validation logic in the codebase

# Search for store validation or existence checks
rg -A 5 'validateStore|checkStore|storeExists|getStore' --type ts --type tsx

Length of output: 106


Refining the search to locate any dynamic route handlers and store‐lookup logic:


🏁 Script executed:

#!/bin/bash
# List any files with dynamic segments (e.g., [subdomain], [store]) in their names
echo "=== Dynamic route files ==="
find . -type f | grep '\[[^]]*\]' | grep -E '\.ts(x)?$' || echo "No dynamic route files found"

# Search for store lookup or validation functions
echo "=== Store lookup / validation functions ==="
rg -Hn "getStore|storeExists|checkStore|validateStore" || echo "None found"

# Search for Next.js notFound() calls (indicating page‐level 404 handling)
echo "=== notFound() usage ==="
rg -Hn "notFound" || echo "None found"

Length of output: 13828


Middleware rewrites are safe: store validation happens at page level

The dynamic store page (app/[store]/page.tsx) fetches store data and invokes notFound() when the slug doesn’t exist—your custom 404 is rendered via app/[...not_found]/page.tsx. As a result, adding a subdomain existence check in the middleware is optional, not required for correctness.

Relevant locations:

  • app/[store]/page.tsx (calls your store‐data API and notFound() on missing stores)
  • app/[...not_found]/page.tsx (renders the 404 UI)

If you still want to short-circuit invalid subdomains at the edge, you could call your /check-store-domain Lambda API in the middleware, but this isn’t necessary with the existing fallback.

Likely an incorrect or invalid review comment.

app/[store]/page.tsx (1)

1-1:

Details

❌ Incorrect review comment

Consider if this component needs to be a client component.

The component doesn't use any client-side features like state, effects, or browser APIs. It could be a server component for better performance.


🌐 Web query:

Can Next.js useParams hook be used in server components in the App Router?

💡 Result:

No, the useParams hook in Next.js cannot be used in server components when using the App Router. The useParams hook is a React hook meant to be used in client components because it relies on React's client-side hooks and context to access route parameters.

In Next.js with the App Router, server components do not support client-only hooks like useParams. Instead, in server components, you retrieve route parameters directly from the props passed to the component or via the params argument in the page or layout component.

For example, in a server component file inside a dynamic route like app/[id]/page.js, you can access params like this:

export default function Page({ params }) {
  const { id } = params;
  // Use `id` here in the server component
  return <div>{id}</div>;
}

If you need to use useParams, you would have to mark the component as a client component by adding 'use client' at the top and then use it inside that client component. However, this pushes the rendering to the client side.

So, in summary:

  • Server components: use params from props or function arguments.
  • Client components: use useParams hook.

Let me know if you'd like an example!


🏁 Script executed:

#!/bin/bash
# Search for any use of the useParams hook in the repository
rg "useParams" -n

Length of output: 3720


‘use client’ is required here: useParams is client-only
useParams from next/navigation cannot be used in server components. This page imports and calls useParams, so it must remain a client component.

• app/[store]/page.tsx (lines 1–6):

 'use client'
-import { useParams } from 'next/navigation'
+// `use client` is needed because useParams() is a client-only hook
 const params = useParams()

Likely an incorrect or invalid review comment.

Comment thread middleware.ts
Comment on lines +17 to +25
const isValidHostname = allowedDomains.some(
domain => hostname === domain || hostname.endsWith(`.${domain}`)
)

// Si el hostname es válido, redirigir a la landing

if (isValidHostname) {
return NextResponse.redirect(new URL('/', request.url))
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the inverted domain validation logic.

The current logic redirects to the root landing page when the hostname matches the main domain (fasttify.com or localhost), which appears to be inverted. This would prevent users from accessing the main site and only allow access via subdomains.

-  const isValidHostname = allowedDomains.some(
-    domain => hostname === domain || hostname.endsWith(`.${domain}`)
-  )
-
-  // Si el hostname es válido, redirigir a la landing
-
-  if (isValidHostname) {
-    return NextResponse.redirect(new URL('/', request.url))
-  }
+  // Check if hostname is main domain (without subdomain)
+  const isMainDomain = allowedDomains.some(domain => {
+    const cleanHostname = hostname.split(':')[0]
+    return cleanHostname === domain || cleanHostname === `www.${domain}`
+  })
+
+  // If accessing main domain, continue with normal routing
+  if (isMainDomain) {
+    return NextResponse.next()
+  }
📝 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
const isValidHostname = allowedDomains.some(
domain => hostname === domain || hostname.endsWith(`.${domain}`)
)
// Si el hostname es válido, redirigir a la landing
if (isValidHostname) {
return NextResponse.redirect(new URL('/', request.url))
}
// Check if hostname is main domain (without subdomain)
const isMainDomain = allowedDomains.some(domain => {
const cleanHostname = hostname.split(':')[0]
return cleanHostname === domain || cleanHostname === `www.${domain}`
})
// If accessing main domain, continue with normal routing
if (isMainDomain) {
return NextResponse.next()
}
🤖 Prompt for AI Agents
In middleware.ts around lines 17 to 25, the domain validation logic is inverted,
causing redirection to the root landing page when the hostname matches the main
domain instead of subdomains. To fix this, reverse the condition so that
redirection happens only when the hostname is not the main domain or localhost,
allowing access to the main site and restricting subdomains as intended.

Comment thread app/[store]/page.tsx
Comment on lines +13 to +17
return (
<div>
<h1>Tienda: {store}</h1>
</div>
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add proper page structure and metadata.

The current implementation is minimal. Consider adding proper HTML structure, metadata, and actual store content.

Would you like me to help implement a more complete store page component with:

  • Proper page title and metadata
  • Store details fetching
  • Loading states
  • Error boundaries
  • SEO optimization
🤖 Prompt for AI Agents
In app/[store]/page.tsx around lines 13 to 17, the current page component lacks
proper HTML structure, metadata, and meaningful store content. Enhance the
component by adding a head section with a descriptive page title and metadata
for SEO. Implement logic to fetch store details dynamically, include loading and
error states to handle asynchronous data fetching gracefully, and structure the
page content to display store information clearly. This will improve user
experience and SEO performance.

@Stivenjs Stivenjs merged commit 060be25 into main Jun 5, 2025
5 checks passed
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