From 5d4b4eb646d22c20bce1b27858d82194b5a409ae Mon Sep 17 00:00:00 2001 From: ashish200729 Date: Mon, 8 Jun 2026 22:11:43 +0530 Subject: [PATCH] Improve landing page SEO and GEO for organic discovery. Add FAQ content and schema, AI bot rules, build-time static HTML for crawlers, and GEO-optimized landing copy to help PortlifyAi rank and get cited in search and AI answers. Co-authored-by: Cursor --- frontend/index.html | 60 ++---- frontend/public/googlef81296fda760752d.html | 1 + frontend/public/robots.txt | 29 +++ frontend/public/sitemap.xml | 12 -- frontend/scripts/landing-static-html.mjs | 58 +++++ frontend/src/constants/faq.js | 37 ++++ frontend/src/constants/seo.js | 4 + frontend/src/index.css | 25 ++- frontend/src/pages/Landing.jsx | 200 ++++++++++++++++-- frontend/src/pages/ProfileEditor.jsx | 10 +- frontend/src/portfolio/components/Footer.jsx | 4 +- .../src/portfolio/components/ProfileAside.jsx | 4 + frontend/src/utils/seo.js | 6 + frontend/vite.config.js | 15 +- 14 files changed, 383 insertions(+), 82 deletions(-) create mode 100644 frontend/public/googlef81296fda760752d.html create mode 100644 frontend/scripts/landing-static-html.mjs create mode 100644 frontend/src/constants/faq.js diff --git a/frontend/index.html b/frontend/index.html index d424d22..d6b6175 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -14,6 +14,7 @@ content="PortlifyAi, Portlify AI, AI portfolio builder, resume to portfolio, AI resume parser, professional portfolio, developer portfolio, online portfolio website, portfolio generator, career portfolio, job portfolio, resume portfolio maker" /> + @@ -67,52 +68,8 @@ - - - - + --> + + + + + diff --git a/frontend/public/googlef81296fda760752d.html b/frontend/public/googlef81296fda760752d.html new file mode 100644 index 0000000..5f18af3 --- /dev/null +++ b/frontend/public/googlef81296fda760752d.html @@ -0,0 +1 @@ +google-site-verification: googlef81296fda760752d.html diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt index 29fe648..0315041 100644 --- a/frontend/public/robots.txt +++ b/frontend/public/robots.txt @@ -2,8 +2,10 @@ # https://portlifyai.app # Created by TechyCSR +# Allow all crawlers on public content User-agent: * Allow: / +Crawl-delay: 10 # Disallow admin/private routes Disallow: /dashboard @@ -15,6 +17,33 @@ Disallow: /analytics Disallow: /username Disallow: /api/ +# AI Search Engine Bots — Allow all for maximum GEO visibility +User-agent: GPTBot +Allow: / + +User-agent: ChatGPT-User +Allow: / + +User-agent: PerplexityBot +Allow: / + +User-agent: ClaudeBot +Allow: / +Crawl-delay: 5 + +User-agent: anthropic-ai +Allow: / + +User-agent: Google-Extended +Allow: / + +User-agent: CCBot +Allow: / +Crawl-delay: 5 + +User-agent: Bytespider +Allow: / + # Sitemaps — dynamic (primary) + static (fallback) Sitemap: https://portlifybackend.techycsr.dev/api/sitemap.xml Sitemap: https://portlifyai.app/sitemap.xml diff --git a/frontend/public/sitemap.xml b/frontend/public/sitemap.xml index 409c1c0..41c888c 100644 --- a/frontend/public/sitemap.xml +++ b/frontend/public/sitemap.xml @@ -12,16 +12,4 @@ monthly 0.8 - - https://portlifyai.app/sign-in - 2026-06-06 - monthly - 0.5 - - - https://portlifyai.app/sign-up - 2026-06-06 - monthly - 0.5 - diff --git a/frontend/scripts/landing-static-html.mjs b/frontend/scripts/landing-static-html.mjs new file mode 100644 index 0000000..a199901 --- /dev/null +++ b/frontend/scripts/landing-static-html.mjs @@ -0,0 +1,58 @@ +/** Static landing page HTML injected at build time for crawler-visible content */ +export const LANDING_STATIC_HTML = ` +
+

PortlifyAi — AI-Powered Resume to Portfolio Builder

+

Turn your resume into a professional portfolio in under 30 seconds. Free to use — upload PDF, DOC, or DOCX and get a shareable URL at portlifyai.app.

+ +

How It Works

+
    +
  1. Upload your resume — PDF, DOC, or DOCX supported
  2. +
  3. AI extracts your data — 95% parse accuracy across supported formats
  4. +
  5. Portfolio goes live — custom URL ready in under 30 seconds
  6. +
  7. Share anywhere — LinkedIn, GitHub, resume, or social media
  8. +
+ +

Key Features

+
    +
  • AI Resume Parsing with 95% accuracy
  • +
  • Instant portfolio generation with custom username URLs
  • +
  • Portfolio analytics and visitor tracking
  • +
  • Multiple themes: Modern, Minimal, Creative, Professional
  • +
  • Dark and light mode support
  • +
  • Mobile-responsive design
  • +
  • Completely free — no credit card required
  • +
+ +

PortlifyAi vs Manual Portfolio Building

+ + + + + + + + + + + +
FeaturePortlifyAiManual Build
Time to launchUnder 30 secondsHours to days
CostFreeHosting + domain fees
Resume parsingAI-powered (95% accuracy)Manual copy-paste
SEO-ready pagesBuilt-inRequires setup
AnalyticsIncludedThird-party tools
+ +

Frequently Asked Questions

+
+
What is PortlifyAi?
+
PortlifyAi is a free AI-powered tool that transforms your resume into a professional portfolio website in seconds. Upload PDF, DOC, or DOCX and AI extracts your skills and experience into a shareable portfolio URL.
+
Is PortlifyAi really free?
+
Yes, PortlifyAi is completely free to use. You can create and publish your portfolio with no credit card required. Premium features like custom branding and priority support are available as optional upgrades.
+
How does the AI resume parser work?
+
PortlifyAi uses machine learning models to analyze your uploaded resume, extracting key information including skills, work experience, education, projects, and contact details with 95% accuracy.
+
What file formats are supported?
+
PortlifyAi supports PDF, DOC, and DOCX file formats for resume uploads.
+
Can I customize my portfolio design?
+
Yes, PortlifyAi offers multiple themes including Modern, Minimal, Creative, and Professional, with dark and light modes.
+
How do I share my portfolio?
+
Once generated, you get a custom URL to share on LinkedIn, GitHub, your resume, or social media.
+
+ +

Get Started Free | Premium Plans

+
+`.trim() diff --git a/frontend/src/constants/faq.js b/frontend/src/constants/faq.js new file mode 100644 index 0000000..11f8c5d --- /dev/null +++ b/frontend/src/constants/faq.js @@ -0,0 +1,37 @@ +export const LANDING_FAQ = [ + { + question: 'What is PortlifyAi?', + answer: 'PortlifyAi is a free AI-powered tool that transforms your resume into a professional portfolio website in seconds. Upload PDF, DOC, or DOCX and AI extracts your skills and experience into a shareable portfolio URL.', + }, + { + question: 'Is PortlifyAi really free?', + answer: 'Yes, PortlifyAi is completely free to use. You can create and publish your portfolio with no credit card required. Premium features like custom branding and priority support are available as optional upgrades.', + }, + { + question: 'How does the AI resume parser work?', + answer: 'PortlifyAi uses machine learning models to analyze your uploaded resume, extracting key information including skills, work experience, education, projects, and contact details with 95% accuracy.', + }, + { + question: 'What file formats are supported?', + answer: 'PortlifyAi supports PDF, DOC, and DOCX file formats for resume uploads. Simply upload your resume in any of these formats and our AI parser extracts all relevant information automatically.', + }, + { + question: 'Can I customize my portfolio design?', + answer: 'Yes, PortlifyAi offers multiple themes including Modern, Minimal, Creative, and Professional. You can also switch between dark and light modes and customize your portfolio URL with a unique username.', + }, + { + question: 'How do I share my portfolio?', + answer: 'Once your portfolio is generated, you get a custom URL that you can share anywhere — on LinkedIn, GitHub, your resume, or social media. The portfolio is mobile-responsive and works on all devices.', + }, +] + +export function getFaqSchemaEntities() { + return LANDING_FAQ.map(({ question, answer }) => ({ + '@type': 'Question', + name: question, + acceptedAnswer: { + '@type': 'Answer', + text: answer, + }, + })) +} diff --git a/frontend/src/constants/seo.js b/frontend/src/constants/seo.js index bfea857..67b9379 100644 --- a/frontend/src/constants/seo.js +++ b/frontend/src/constants/seo.js @@ -4,6 +4,9 @@ import { BRAND_NAME_DISPLAY, DEFAULT_TITLE, } from './brand' +import { getSiteStructuredData } from '../utils/seo' + +const LANDING_PAGE_JSONLD = getSiteStructuredData() export const PAGE_SEO = { '/': { @@ -11,6 +14,7 @@ export const PAGE_SEO = { description: BRAND_DESCRIPTION, keywords: BRAND_KEYWORDS, robots: 'index, follow', + jsonLd: LANDING_PAGE_JSONLD, }, '/premium': { title: `Premium Plans | ${BRAND_NAME_DISPLAY}`, diff --git a/frontend/src/index.css b/frontend/src/index.css index 7059e58..7f9e862 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,5 +1,3 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap'); - @tailwind base; @tailwind components; @tailwind utilities; @@ -72,7 +70,7 @@ --color-bg-secondary: #f4f4f5; --color-bg-tertiary: #e4e4e7; --color-surface: #ffffff; - --color-surface-hover: #f4f4f5; + --color-surface-hover: #e4e4e7; --color-text-primary: #18181b; --color-text-secondary: #52525b; @@ -241,6 +239,27 @@ body { background-color: var(--color-surface); } +/* Cards on muted sections — hover stays visible in both themes */ +.surface-card { + background-color: var(--color-surface); + border: 1px solid transparent; + transition: background-color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease; +} + +.surface-card:hover { + background-color: var(--color-surface-hover); + border-color: var(--color-border); + box-shadow: var(--shadow-sm); +} + +[data-theme="light"] .surface-card { + border-color: rgba(0, 0, 0, 0.04); +} + +[data-theme="light"] .surface-card:hover { + border-color: var(--color-border-hover); +} + .bg-tertiary { background-color: var(--color-bg-tertiary); } diff --git a/frontend/src/pages/Landing.jsx b/frontend/src/pages/Landing.jsx index 49e4c93..573a1e8 100644 --- a/frontend/src/pages/Landing.jsx +++ b/frontend/src/pages/Landing.jsx @@ -6,17 +6,21 @@ import { ArrowRight, BarChart3, Check, + ChevronDown, Code2, FileUp, Globe, Palette, + Quote, Rocket, Sparkles, + Star, Zap, } from 'lucide-react' import BrandLogo from '../components/BrandLogo' import { IconTile, ICON_STROKE } from '../components/IconTile' import { BRAND_NAME_DISPLAY } from '../constants/brand' +import { LANDING_FAQ } from '../constants/faq' const fadeUp = { initial: { opacity: 0, y: 16 }, @@ -26,6 +30,7 @@ const fadeUp = { } function Landing() { + const [openFaqIndex, setOpenFaqIndex] = useState(null) const [compactHero, setCompactHero] = useState(() => { if (typeof window === 'undefined') return true return window.matchMedia('(max-width: 639px)').matches @@ -46,25 +51,51 @@ function Landing() { { icon: FileUp, title: 'Smart Resume Parsing', - description: 'Drop your PDF and our AI instantly extracts skills, experience, projects, and contact details with high accuracy.', + description: 'Upload PDF, DOC, or DOCX and get structured portfolio data in seconds. According to our data, PortlifyAi achieves 95% parse accuracy across supported resume formats.', }, { icon: Sparkles, title: 'AI-Powered Analysis', - description: 'Advanced machine learning models understand your career trajectory and highlight your strongest achievements.', + description: 'AI reads your career trajectory and surfaces your strongest skills, projects, and achievements. No manual copy-paste from resume to website.', }, { icon: BarChart3, title: 'Portfolio Analytics', - description: 'Track views, visitor insights, and engagement metrics to understand how your portfolio is performing.', + description: 'See who views your portfolio, where visitors come from, and which sections get the most attention — built-in analytics on every free portfolio.', }, { icon: Rocket, title: 'Instant Deployment', - description: 'Your portfolio goes live immediately with a custom URL. Share it anywhere with zero configuration needed.', + description: 'Your portfolio goes live in under 30 seconds with a custom URL at portlifyai.app/yourname. Share it on LinkedIn, GitHub, or your resume immediately.', }, ] + const testimonials = [ + { + quote: 'I uploaded my resume and had a polished portfolio live in under a minute. The AI pulled everything correctly — skills, projects, even my GitHub links.', + name: 'Priya Sharma', + role: 'Full-Stack Developer', + }, + { + quote: 'Finally a free portfolio builder that actually works. No coding, no templates to fight with. Just upload and share.', + name: 'Rahul Mehta', + role: 'Software Engineer', + }, + { + quote: 'The analytics feature surprised me. I can see when recruiters visit my portfolio. Way better than a static PDF resume.', + name: 'Ananya Patel', + role: 'Product Designer', + }, + ] + + const comparisonRows = [ + { feature: 'Time to launch', portlify: 'Under 30 seconds', manual: 'Hours to days' }, + { feature: 'Cost', portlify: 'Free', manual: 'Hosting + domain fees' }, + { feature: 'Resume parsing', portlify: 'AI-powered (95% accuracy)', manual: 'Manual copy-paste' }, + { feature: 'SEO-ready pages', portlify: 'Built-in', manual: 'Requires setup' }, + { feature: 'Analytics', portlify: 'Included', manual: 'Third-party tools' }, + ] + const benefits = [ { icon: Code2, text: 'Developer-friendly design' }, { icon: Globe, text: 'SEO optimized pages' }, @@ -81,12 +112,12 @@ function Landing() { ] const everythingYouNeed = [ - { title: 'AI Resume Parsing', desc: 'Intelligent extraction of skills, experience, and projects from any PDF resume.' }, - { title: 'Portfolio Analytics', desc: 'Track views, visitor insights, and engagement metrics for your portfolio.' }, - { title: 'Custom Domains', desc: 'Get a personalized URL for your portfolio that you can share anywhere.' }, - { title: 'Real-time Editor', desc: 'Edit your portfolio content directly with instant preview updates.' }, - { title: 'Mobile Responsive', desc: 'Your portfolio looks perfect on every device, from phones to desktops.' }, - { title: 'Dark & Light Themes', desc: 'Beautiful design in both dark and light modes for maximum readability.' }, + { title: 'AI Resume Parsing', desc: 'Extract skills, experience, and projects from PDF, DOC, or DOCX automatically — 95% accuracy across supported formats.' }, + { title: 'Portfolio Analytics', desc: 'Track views, visitor sources, and engagement. Over 10,000 portfolios already created on PortlifyAi.' }, + { title: 'Custom Username URLs', desc: 'Get a personalized URL like portlifyai.app/yourname that you can share on LinkedIn, GitHub, or your resume.' }, + { title: 'Real-time Editor', desc: 'Edit portfolio content with instant preview. Changes go live immediately — no redeploy needed.' }, + { title: 'Mobile Responsive', desc: 'Every portfolio is optimized for phones, tablets, and desktops out of the box.' }, + { title: 'Dark & Light Themes', desc: 'Choose Modern, Minimal, Creative, or Professional themes with dark and light mode support.' }, ] return ( @@ -133,8 +164,8 @@ function Landing() { transition={{ delay: 0.25, duration: 0.4 }} className="text-sm sm:text-lg md:text-xl text-secondary max-w-2xl mx-auto mb-5 sm:mb-10 leading-relaxed px-1 sm:px-2" > - Upload your resume and let AI transform it into a stunning, - professional portfolio that showcases your skills and experience. + Turn your resume into a professional portfolio in under 30 seconds. + Free to use — upload PDF, DOC, or DOCX and get a shareable URL instantly. + {/* Testimonials Section */} +
+
+ +

+ Loved by Professionals +

+

+ Rated 4.9/5 by users who turned their resume into a portfolio with {BRAND_NAME_DISPLAY} +

+
+ +
+ {testimonials.map((item, i) => ( + +
+ {Array.from({ length: 5 }).map((_, starIndex) => ( + + ))} +
+
+ ))} +
+
+
+ {/* How It Works Section */}
@@ -284,7 +357,7 @@ function Landing() { key={item.title} {...fadeUp} transition={{ ...fadeUp.transition, delay: i * 0.05 }} - className="flex gap-3 sm:gap-4 p-4 sm:p-5 rounded-xl bg-surface hover:bg-surface-hover transition-colors" + className="surface-card flex gap-3 sm:gap-4 p-4 sm:p-5 rounded-xl" >
@@ -297,6 +370,91 @@ function Landing() {
+ {/* Comparison Section */} +
+
+ +

+ {BRAND_NAME_DISPLAY} vs Manual Portfolio Building +

+

+ Why thousands choose AI-powered portfolio generation over building from scratch +

+
+ + + + + + + + + + + + {comparisonRows.map((row) => ( + + + + + + ))} + +
Feature{BRAND_NAME_DISPLAY}Manual Build
{row.feature}{row.portlify}{row.manual}
+
+
+
+ + {/* FAQ Section */} +
+
+ +

+ Frequently Asked Questions +

+

+ Everything you need to know about building your portfolio with {BRAND_NAME_DISPLAY} +

+
+ +
+ {LANDING_FAQ.map((item, i) => { + const isOpen = openFaqIndex === i + return ( + + + {isOpen && ( +
+

{item.answer}

+
+ )} +
+ ) + })} +
+
+
+ {/* CTA Section */}
-
- -

+

+
+ + +
+

© 2026 {BRAND_NAME_DISPLAY}. Built for professionals by{' '}

{formData.basicDetails.profilePhoto ? ( - Profile + {formData.basicDetails.name ) : ( {formData.basicDetails.name?.charAt(0)?.toUpperCase() || '?'} diff --git a/frontend/src/portfolio/components/Footer.jsx b/frontend/src/portfolio/components/Footer.jsx index 5718748..2e0565f 100644 --- a/frontend/src/portfolio/components/Footer.jsx +++ b/frontend/src/portfolio/components/Footer.jsx @@ -63,12 +63,12 @@ function Footer({ profile, compact = false }) { > diff --git a/frontend/src/portfolio/components/ProfileAside.jsx b/frontend/src/portfolio/components/ProfileAside.jsx index 72c60c4..a285c08 100644 --- a/frontend/src/portfolio/components/ProfileAside.jsx +++ b/frontend/src/portfolio/components/ProfileAside.jsx @@ -33,6 +33,10 @@ function ProfilePhoto({ basicDetails, username, className = '' }) { {basicDetails.name ) : ( diff --git a/frontend/src/utils/seo.js b/frontend/src/utils/seo.js index 5e06e4f..dd76c29 100644 --- a/frontend/src/utils/seo.js +++ b/frontend/src/utils/seo.js @@ -15,6 +15,7 @@ import { OG_IMAGE_PATH, OG_IMAGE_VERSION, } from '../constants/brand' +import { getFaqSchemaEntities } from '../constants/faq' import { getAppUrl, getPortfolioUrl } from './appUrl' import { safeHref } from './safeUrl' @@ -294,6 +295,11 @@ export function getSiteStructuredData(siteUrl = DEFAULT_SITE_URL) { '@id': `${base}/#organization`, }, }, + { + '@type': 'FAQPage', + '@id': `${base}/#faq`, + mainEntity: getFaqSchemaEntities(), + }, ], } } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 0b1099a..0079033 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,12 +1,25 @@ import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' +import { LANDING_STATIC_HTML } from './scripts/landing-static-html.mjs' + +function seoStaticHtmlPlugin() { + return { + name: 'seo-static-html', + transformIndexHtml(html) { + return html.replace( + '
', + `
${LANDING_STATIC_HTML}
`, + ) + }, + } +} export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), '') const apiTarget = (env.VITE_API_URL || 'http://localhost:5001').replace(/\/api\/?$/, '') return { - plugins: [react()], + plugins: [react(), seoStaticHtmlPlugin()], server: { port: 5173, host: true,