Skip to content

Commit

Permalink
Merge pull request #678 from RobinNagpal/sherwani/Seo-changes-and-sit…
Browse files Browse the repository at this point in the history
…emap

seo changes and sitemap for insights site
  • Loading branch information
RobinNagpal authored Feb 10, 2025
2 parents 2f3df51 + b83cc22 commit 8fa1593
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 36 deletions.
9 changes: 9 additions & 0 deletions insights-ui/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# *
User-agent: *
Allow: /

# Host
Host: https://agentic-insights.dodao.io/

# Sitemaps
Sitemap: https://agentic-insights.dodao.io/sitemap.xml
27 changes: 10 additions & 17 deletions insights-ui/src/app/crowd-funding/projects/[projectId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@ export async function generateMetadata({ params }: { params: Promise<{ projectId

return {
title: `${data.projectDetails.name} - Crowdfunding Project | DoDAO`,
description: `Learn more about the crowdfunding project "${data.projectDetails.name}". Explore funding details, project insights, and official links.`,
description: `DoDAO Agentic Insights provides detailed analysis and insights for "${data.projectDetails.name}" with graphs, reports and metrics like growth,financial health ,traction, valuation ,Execution and speed.`,
keywords: [
'Crowdfunding',
'Blockchain',
'Funding',
'Traction',
'Investment',
'Market Opportunity',
'Execution and Speed',
'Team',
'Valuation',
data.projectDetails.name,
'Wefunder',
'Kickstarter',
'Start Engine',
'Indiegogo',
'Insights',
'Financial',
'Project',
'Analysis',
'Evaluations',
],
robots: {
index: true,
Expand All @@ -41,17 +40,11 @@ export async function generateMetadata({ params }: { params: Promise<{ projectId
},
openGraph: {
title: `${data.projectDetails.name} - Crowdfunding Project | DoDAO`,
description: `Explore project details, funding status, and insights for "${data.projectDetails.name}".`,
description: `DoDAO Agentic Insights provides detailed analysis and insights for "${data.projectDetails.name}" with graphs, reports and metrics like growth,financial health ,traction, valuation ,Execution and speed.`,
url: `https://agentic-insights.dodao.io/crowd-funding/projects/${projectId}`,
type: 'website',
siteName: 'DoDAO',
},
twitter: {
card: 'summary_large_image',
title: `${data.projectDetails.name} - Crowdfunding Project | DoDAO`,
description: `Discover more about "${data.projectDetails.name}". Get details, reports, and funding status.`,
site: '@dodao_io',
creator: '@dodao_io',
images: [data.projectDetails.imgUrl || ''],
siteName: 'Agentic Insights - DoDao',
},
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,44 @@ import remarkGfm from 'remark-gfm';
import { BreadcrumbsOjbect } from '@dodao/web-core/components/core/breadcrumbs/BreadcrumbsWithChevrons';
import { Metadata } from 'next';
import Breadcrumbs from '@/components/ui/Breadcrumbs';
import { ProjectDetails, SpiderGraph } from '@/types/project/project';
import { ProjectDetails, ReportType, SpiderGraph } from '@/types/project/project';

export async function generateMetadata({ params }: { params: Promise<{ projectId: string; reportType: string }> }): Promise<Metadata> {
const { projectId, reportType } = await params;

const projectResponse = await fetch(`${getBaseUrl()}/api/crowd-funding/projects/${projectId}`);
const projectData: { projectDetails: ProjectDetails; spiderGraph: SpiderGraph | {} } = await projectResponse.json();

const report = projectData.projectDetails.reports[reportType];

// Map report types to better human-readable titles
const reportTitles: Record<string, string> = {
general_info: 'General Information',
red_flags: 'Red Flags',
green_flags: 'Green Flags',
team_info: 'Team Information',
financial_review: 'Financial Review',
relevant_links: 'Relevant Links',
[ReportType.GENERAL_INFO]: 'General Information',
[ReportType.FOUNDER_AND_TEAM]: 'Founder and Team',
[ReportType.TRACTION]: 'Traction',
[ReportType.MARKET_OPPORTUNITY]: 'Market Opportunity',
[ReportType.VALUATION]: 'Valuation',
[ReportType.EXECUTION_AND_SPEED]: 'Execution and Speed',
[ReportType.FINANCIAL_HEALTH]: 'Financial Health',
[ReportType.RELEVANT_LINKS]: 'Relevant Links',
};

// Default title if the report type is unknown
const readableReportType = reportTitles[reportType] || 'Project Report';

return {
title: `${readableReportType} - ${projectId} | DoDAO`,
description: `Explore the ${readableReportType} for the crowdfunding project "${projectId}". Get insights into funding status, risks, and investment potential.`,
description: `Explore the ${readableReportType} for the crowdfunding project "${projectId}". ${report.summary || ''}`,
keywords: [
'project report',
'blockchain funding',
'crowdfunding insights',
'investment analysis',
'investor reports',
'analysis',
'team assessment',
'risk analysis',
reportType, // Dynamic keyword from report type
'investment risks',
'funding health',
projectId,
readableReportType, // Dynamic keyword from report type
],
robots: {
index: true,
Expand All @@ -51,13 +58,6 @@ export async function generateMetadata({ params }: { params: Promise<{ projectId
type: 'article',
siteName: 'DoDAO',
},
twitter: {
card: 'summary_large_image',
title: `${readableReportType} - ${projectId} | DoDAO`,
description: `Discover the ${readableReportType} for project "${projectId}". Get details on funding, risks, and team evaluation.`,
site: '@dodao_io',
creator: '@dodao_io',
},
};
}

Expand Down
94 changes: 94 additions & 0 deletions insights-ui/src/app/sitemap.xml/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { ReportType } from '@/types/project/project';
import getBaseUrl from '@dodao/web-core/utils/api/getBaseURL';
import { NextRequest, NextResponse } from 'next/server';
import { SitemapStream, streamToPromise } from 'sitemap';

interface SiteMapUrl {
url: string;
changefreq: string;
priority?: number;
}

// Fetch all project IDs
async function getAllProjects(): Promise<string[]> {
const baseUrl = getBaseUrl();
try {
const response = await fetch(`${baseUrl}/crowd-funding/projects`, {
method: 'GET',
});

if (!response.ok) {
throw new Error(`Failed to fetch projects: ${response.statusText}`);
}

const data = await response.json();
return data.projectIds || [];
} catch (error) {
console.error('Error fetching projects:', error);
return []; // Return an empty array to prevent breaking the sitemap
}
}

// Generate sitemap URLs
async function generateSitemapUrls(): Promise<SiteMapUrl[]> {
const projectIds = await getAllProjects();
const urls: SiteMapUrl[] = [];

// Add home page URL
urls.push({
url: '/',
changefreq: 'daily',
priority: 1.0,
});

if (projectIds.length === 0) {
console.warn('No projects found for the sitemap.');
return urls; // Return at least the home page URL
}

for (const projectId of projectIds) {
urls.push({
url: `/crowd-funding/projects/${projectId}`,
changefreq: 'weekly',
priority: 0.8,
});

for (const reportType of Object.values(ReportType)) {
urls.push({
url: `/crowd-funding/projects/${projectId}/reports/${reportType}`,
changefreq: 'weekly',
priority: 0.7,
});
}
}

return urls;
}

// Handle GET request for sitemap
async function GET(req: NextRequest): Promise<NextResponse<Buffer>> {
try {
const baseUrl = getBaseUrl();
const urls = await generateSitemapUrls();
const smStream = new SitemapStream({ hostname: baseUrl });

for (const url of urls) {
smStream.write(url);
}

smStream.end();
const response: Buffer = await streamToPromise(smStream);

return new NextResponse(response, {
status: 200,
headers: {
'Content-Type': 'application/xml',
},
});
} catch (error) {
console.error('Error generating sitemap:', error);
return new NextResponse('Internal Server Error', { status: 500 });
}
}

export { GET };

0 comments on commit 8fa1593

Please sign in to comment.