diff --git a/app/blog/page.tsx b/app/blog/page.tsx index 319bd83..0a61126 100644 --- a/app/blog/page.tsx +++ b/app/blog/page.tsx @@ -10,6 +10,9 @@ export const metadata: Metadata = { title: 'Blog | Frontend Development Insights & Tutorials', description: 'Deep dives into frontend development, performance optimization, React patterns, CSS techniques, and industry best practices from the Frontend Junction community.', + alternates: { + canonical: 'https://www.frontend-junction.com/blog', + }, }; const POSTS_PER_PAGE = 6; // Changed to 6 for better grid (2x3) diff --git a/app/companies/[company]/page.tsx b/app/companies/[company]/page.tsx index f061e25..ef50e7b 100644 --- a/app/companies/[company]/page.tsx +++ b/app/companies/[company]/page.tsx @@ -6,8 +6,7 @@ import { Metadata } from 'next'; import Script from 'next/script'; import { FaCalendar, FaUser } from 'react-icons/fa'; -export const dynamic = 'force-dynamic'; -export const revalidate = 600; // Cache for 10 minutes +export const revalidate = 600; // ISR: revalidate every 10 minutes interface Props { params: Promise<{ company: string }>; @@ -32,6 +31,9 @@ export async function generateMetadata({ params }: Props): Promise { `${companyName} software engineer interview`, `${companyName} react interview`, ], + alternates: { + canonical: `https://www.frontend-junction.com/companies/${company}`, + }, openGraph: { title: `${companyName} Frontend Interview Experiences`, description: `Browse real ${companyName} frontend engineer interview experiences.`, diff --git a/app/companies/page.tsx b/app/companies/page.tsx index 86a82db..096f8d5 100644 --- a/app/companies/page.tsx +++ b/app/companies/page.tsx @@ -3,13 +3,15 @@ import Link from 'next/link'; import { Metadata } from 'next'; import Script from 'next/script'; -export const dynamic = 'force-dynamic'; -export const revalidate = 3600; // Cache for 1 hour +export const revalidate = 3600; // ISR: revalidate every 1 hour export const metadata: Metadata = { title: 'Top Companies for Frontend Interviews | Frontend Junction', description: 'Browse frontend interview experiences by company. Prepare for your next interview at Google, Amazon, Uber, and more.', + alternates: { + canonical: 'https://www.frontend-junction.com/companies', + }, openGraph: { title: 'Top Companies for Frontend Interviews', description: diff --git a/app/error.tsx b/app/error.tsx new file mode 100644 index 0000000..724a910 --- /dev/null +++ b/app/error.tsx @@ -0,0 +1,36 @@ +'use client'; + +import Link from 'next/link'; + +export default function Error({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ( +
+

Oops!

+

Something went wrong

+

+ An unexpected error occurred. Please try again or navigate to another + page. +

+
+ + + Go Home + +
+
+ ); +} diff --git a/app/interview-experience/[slug]/page.tsx b/app/interview-experience/[slug]/page.tsx index 0523170..11e5a39 100644 --- a/app/interview-experience/[slug]/page.tsx +++ b/app/interview-experience/[slug]/page.tsx @@ -1,4 +1,5 @@ import { getExperienceBySlug } from '@/lib/getExperienceBySlug'; +import { sanitizeHtml } from '@/lib/sanitize-html'; import { notFound } from 'next/navigation'; import Link from 'next/link'; import { FaExternalLinkAlt, FaCalendar, FaUser } from 'react-icons/fa'; @@ -7,8 +8,7 @@ import ReactMarkdown from 'react-markdown'; import ViewCounter from '@/components/view-counter'; import Script from 'next/script'; -export const dynamic = 'force-dynamic'; -export const revalidate = 60; // ISR +export const revalidate = 60; // ISR: revalidate every 60 seconds interface Props { params: Promise<{ slug: string }>; @@ -202,7 +202,7 @@ export default async function ExperienceSlugPage({ params }: Props) { {/* Content Analysis (AI Generated or Raw) */}
{experience.content?.trim().startsWith('<') ? ( -
+
) : ( {experience.content || experience.summary || ''} diff --git a/app/interview-experience/page.tsx b/app/interview-experience/page.tsx index 0d0f2df..689501b 100644 --- a/app/interview-experience/page.tsx +++ b/app/interview-experience/page.tsx @@ -8,21 +8,23 @@ import { Suspense } from 'react'; import Loading from '../loading'; export const dynamic = 'force-dynamic'; -export const revalidate = 0; export const metadata: Metadata = { - title: 'Interview Experience', + title: 'Frontend Interview Experiences | Real Stories from Top Companies', description: - 'Browse through real front-end interview experiences from candidates at various companies. Get insights, tips, and prepare better for your next interview.', + 'Browse 400+ real frontend interview experiences from Google, Amazon, Meta, Flipkart, and more. Get insights, tips, and prepare better for your next interview.', keywords: - 'front-end interview experiences, front-end developer interviews, front-end interview preparation, front-end interview insights, front-end interview stories', + 'frontend interview experiences, frontend developer interviews, frontend interview preparation, frontend interview insights, frontend interview stories', + alternates: { + canonical: 'https://www.frontend-junction.com/interview-experience', + }, openGraph: { type: 'website', url: 'https://www.frontend-junction.com/interview-experience', - title: 'Front-end Interview Experiences | Front-end Junction', + title: 'Frontend Interview Experiences | Real Stories from Top Companies', description: - 'Browse through real front-end interview experiences from candidates at various companies. Get insights, tips, and prepare better for your next interview.', - siteName: 'Front-end Junction', + 'Browse 400+ real frontend interview experiences from Google, Amazon, Meta, Flipkart, and more.', + siteName: 'Frontend Junction', }, }; diff --git a/app/layout.tsx b/app/layout.tsx index a919598..7d1983e 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import './globals.css'; import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; import { cn } from '@/lib/utils'; import { SiteHeader } from '@/components/common/site-header'; import { ThemeProvider } from '@/components/common/theme-provider'; @@ -13,6 +14,12 @@ import { } from '@/components/structured-data'; import { Analytics } from '@vercel/analytics/next'; +const inter = Inter({ + subsets: ['latin'], + display: 'swap', + variable: '--font-inter', +}); + export const metadata: Metadata = { metadataBase: new URL('https://www.frontend-junction.com'), title: { @@ -99,12 +106,12 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - +