chore: strip marketing content for public core repo#108
Conversation
Remove blog, docs, catalog, roadmap pages and content. Remove @nuxt/content, @nuxtjs/seo, @nuxtjs/mdc, @tailwindcss/typography deps. Replace useSchemaOrg with manual JSON-LD in job detail page. Simplify PublicNavBar for self-hosters. Add redirect index.vue (marketing layer overrides this).
|
🚅 Deployed to the reqcore-pr-108 environment in applirank
|
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR removes a large portion of the public site and content: many docs, blog posts, catalog/spec pages, topical/SEO artifacts, dynamic sitemap, Nuxt Content/SEO integrations, several page components (blog, docs, catalog, roadmap), the Giscus widget, and related Nuxt configuration—leaving a minimal, auth-focused landing. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/pages/jobs/`[slug]/index.vue:
- Around line 147-158: The JSON-LD script injected via useHead is missing a
deduplication key, so repeated watchEffect runs append duplicate <script
type="application/ld+json"> tags; update the script entry passed to useHead (the
object in the script array where innerHTML: JSON.stringify({ '@context':
'https://schema.org', ...posting })) to include a unique key (e.g., use
posting.id or a fixed 'job-jsonld' key) so Nuxt can dedupe, or alternatively
compute the JSON-LD in a computed ref and call useHead once at top-level in the
<script setup>.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 06f86bd3-80d1-4b48-9649-afe8a832f7d9
📒 Files selected for processing (82)
TOPICAL-AUTHORITY-MAP.mdapp/components/GiscusComments.vueapp/components/PublicNavBar.vueapp/pages/blog/[...slug].vueapp/pages/blog/index.vueapp/pages/catalog/index.vueapp/pages/docs/[...slug].vueapp/pages/docs/index.vueapp/pages/index.vueapp/pages/jobs/[slug]/index.vueapp/pages/roadmap.vuecontent.config.tscontent/blog/best-free-ats-software-for-startups.mdcontent/blog/best-open-source-applicant-tracking-systems.mdcontent/blog/career-page-seo.mdcontent/blog/career-page-that-converts.mdcontent/blog/google-for-jobs-structured-data.mdcontent/blog/greenhouse-vs-open-source-ats.mdcontent/blog/how-applicant-tracking-systems-work.mdcontent/blog/open-source-applicant-tracking-system.mdcontent/blog/open-source-vs-free-ats.mdcontent/blog/opencats-vs-reqcore.mdcontent/blog/self-hosted-vs-cloud-ats.mdcontent/blog/total-cost-of-ownership-saas-ats-vs-self-hosted.mdcontent/blog/who-uses-open-source-ats.mdcontent/catalog/ai-intelligence/ai-ranking/index.mdcontent/catalog/ai-intelligence/index.mdcontent/catalog/ai-intelligence/local-ai/index.mdcontent/catalog/ai-intelligence/resume-parsing/index.mdcontent/catalog/applicant-management/email-communication/index.mdcontent/catalog/applicant-management/index.mdcontent/catalog/applicant-management/phone-communication/index.mdcontent/catalog/collaboration/candidate-portal/index.mdcontent/catalog/collaboration/email-notifications/index.mdcontent/catalog/collaboration/index.mdcontent/catalog/collaboration/interview-scheduling/index.mdcontent/catalog/collaboration/team-comments/index.mdcontent/catalog/mobile-support/index.mdcontent/catalog/mobile-support/responsive-dashboard/index.mdcontent/catalog/pipeline-management/application-tracking/index.mdcontent/catalog/pipeline-management/candidate-profiles/index.mdcontent/catalog/pipeline-management/index.mdcontent/catalog/pipeline-management/job-management/index.mdcontent/catalog/pipeline-management/kanban-board/index.mdcontent/catalog/platform/dashboard/index.mdcontent/catalog/platform/deployment/index.mdcontent/catalog/platform/index.mdcontent/catalog/platform/multi-tenant/index.mdcontent/catalog/recruitment-tools/custom-application-forms/index.mdcontent/catalog/recruitment-tools/document-storage/index.mdcontent/catalog/recruitment-tools/index.mdcontent/catalog/recruitment-tools/public-job-board/index.mdcontent/catalog/security-compliance/gdpr/index.mdcontent/catalog/security-compliance/index.mdcontent/catalog/security-compliance/rate-limiting/index.mdcontent/catalog/security-compliance/server-proxied-documents/index.mdcontent/docs/1.getting-started/1.introduction.mdcontent/docs/1.getting-started/2.installation.mdcontent/docs/1.getting-started/3.configuration.mdcontent/docs/1.getting-started/4.quick-start.mdcontent/docs/2.deployment/1.docker-compose.mdcontent/docs/2.deployment/2.railway.mdcontent/docs/2.deployment/3.environment-variables.mdcontent/docs/3.features/1.job-management.mdcontent/docs/3.features/2.candidate-pipeline.mdcontent/docs/3.features/3.document-storage.mdcontent/docs/3.features/4.public-job-board.mdcontent/docs/3.features/5.application-forms.mdcontent/docs/3.features/6.dashboard.mdcontent/docs/3.features/7.google-calendar.mdcontent/docs/4.architecture/1.overview.mdcontent/docs/4.architecture/2.directory-structure.mdcontent/docs/4.architecture/3.data-model.mdcontent/docs/4.architecture/4.security.mdcontent/docs/5.contributing/1.development-setup.mdcontent/docs/5.contributing/2.coding-conventions.mdcontent/docs/6.legal/1.privacy-policy.mdnuxt.config.tspackage.jsonseo-research/source-package-opencats-vs-reqcore.mdseo-research/topic-brief-opencats-vs-reqcore.mdserver/api/__sitemap__/urls.ts
💤 Files with no reviewable changes (79)
- content/catalog/platform/multi-tenant/index.md
- content/catalog/security-compliance/rate-limiting/index.md
- content/catalog/recruitment-tools/index.md
- content/docs/3.features/1.job-management.md
- content/blog/career-page-seo.md
- content/catalog/pipeline-management/job-management/index.md
- app/pages/blog/[...slug].vue
- content/docs/4.architecture/2.directory-structure.md
- app/components/PublicNavBar.vue
- content/docs/4.architecture/3.data-model.md
- content/docs/1.getting-started/3.configuration.md
- content/catalog/security-compliance/gdpr/index.md
- content/docs/3.features/7.google-calendar.md
- content/catalog/collaboration/team-comments/index.md
- content/catalog/security-compliance/index.md
- content/blog/opencats-vs-reqcore.md
- content/docs/5.contributing/2.coding-conventions.md
- TOPICAL-AUTHORITY-MAP.md
- content/docs/2.deployment/3.environment-variables.md
- content/catalog/pipeline-management/kanban-board/index.md
- content/docs/2.deployment/2.railway.md
- content.config.ts
- content/blog/who-uses-open-source-ats.md
- content/catalog/collaboration/email-notifications/index.md
- content/blog/how-applicant-tracking-systems-work.md
- content/docs/3.features/6.dashboard.md
- content/catalog/collaboration/interview-scheduling/index.md
- content/catalog/platform/index.md
- content/blog/career-page-that-converts.md
- content/docs/5.contributing/1.development-setup.md
- content/catalog/ai-intelligence/local-ai/index.md
- content/docs/6.legal/1.privacy-policy.md
- content/catalog/recruitment-tools/document-storage/index.md
- content/blog/greenhouse-vs-open-source-ats.md
- content/catalog/pipeline-management/candidate-profiles/index.md
- content/docs/3.features/2.candidate-pipeline.md
- content/docs/3.features/5.application-forms.md
- content/docs/1.getting-started/1.introduction.md
- content/catalog/security-compliance/server-proxied-documents/index.md
- content/blog/best-open-source-applicant-tracking-systems.md
- content/docs/3.features/3.document-storage.md
- content/catalog/collaboration/candidate-portal/index.md
- content/catalog/ai-intelligence/index.md
- app/pages/blog/index.vue
- content/catalog/ai-intelligence/ai-ranking/index.md
- content/catalog/recruitment-tools/public-job-board/index.md
- server/api/sitemap/urls.ts
- content/docs/4.architecture/4.security.md
- seo-research/topic-brief-opencats-vs-reqcore.md
- content/catalog/collaboration/index.md
- content/catalog/applicant-management/phone-communication/index.md
- content/docs/1.getting-started/2.installation.md
- content/catalog/pipeline-management/index.md
- content/catalog/mobile-support/index.md
- package.json
- content/catalog/applicant-management/index.md
- content/docs/3.features/4.public-job-board.md
- content/catalog/applicant-management/email-communication/index.md
- content/docs/1.getting-started/4.quick-start.md
- content/catalog/recruitment-tools/custom-application-forms/index.md
- app/pages/roadmap.vue
- content/blog/open-source-vs-free-ats.md
- content/catalog/platform/dashboard/index.md
- content/blog/self-hosted-vs-cloud-ats.md
- content/catalog/mobile-support/responsive-dashboard/index.md
- content/blog/open-source-applicant-tracking-system.md
- app/pages/docs/index.vue
- content/catalog/platform/deployment/index.md
- content/docs/2.deployment/1.docker-compose.md
- content/blog/google-for-jobs-structured-data.md
- seo-research/source-package-opencats-vs-reqcore.md
- content/catalog/pipeline-management/application-tracking/index.md
- app/pages/catalog/index.vue
- content/blog/best-free-ats-software-for-startups.md
- content/catalog/ai-intelligence/resume-parsing/index.md
- content/docs/4.architecture/1.overview.md
- content/blog/total-cost-of-ownership-saas-ats-vs-self-hosted.md
- app/components/GiscusComments.vue
- app/pages/docs/[...slug].vue
| // Inject JSON-LD as a <script> tag (works without @nuxtjs/seo) | ||
| useHead({ | ||
| script: [ | ||
| { | ||
| type: 'application/ld+json', | ||
| innerHTML: JSON.stringify({ | ||
| '@context': 'https://schema.org', | ||
| ...posting, | ||
| }), | ||
| }, | ||
| ], | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Nuxt 4 useHead script key deduplication
💡 Result:
In Nuxt 4, useHead() is powered by Unhead, and script deduplication is controlled via a key you set on each tag.
- If the same
keyappears again in a lateruseHead()call, Unhead will dedupe by replacing the earlier tag with the new one (so you don’t end up with duplicates). [1] - Nuxt’s
useHeadsupportsscript: Script[]where each object becomes a<script>tag (so you can addkeyalongsidesrc,async, etc.). [2]
Example (dedupe across components/layouts/pages):
useHead({
script: [
{ key: 'stripe-js', src: 'https://js.stripe.com/v3/', async: true }
]
})If you’re using Nuxt “head components” (e.g., <Head>, <Script>) rather than useHead, note Nuxt 4.3 included a fix for deduplication using the key attribute. [3]
Sources: Unhead tag deduplication docs [1], Nuxt 4 useHead docs [2], Nuxt 4.3 release notes [3].
🏁 Script executed:
cat -n app/pages/jobs/[slug]/index.vue | sed -n '130,170p'Repository: reqcore-inc/reqcore
Length of output: 1250
🏁 Script executed:
cat -n app/pages/jobs/[slug]/index.vue | sed -n '110,159p'Repository: reqcore-inc/reqcore
Length of output: 1592
🏁 Script executed:
cat -n app/pages/jobs/[slug]/index.vue | sed -n '70,115p'Repository: reqcore-inc/reqcore
Length of output: 1480
Add a key to dedupe the JSON-LD script tag.
Calling useHead inside watchEffect without a deduplication key can cause multiple <script type="application/ld+json"> tags to accumulate when the effect re-runs. Nuxt dedupes head entries by key, so without one each invocation appends a new script.
♻️ Proposed fix: add a key for deduplication
useHead({
script: [
{
+ key: 'job-posting-jsonld',
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org',
...posting,
}),
},
],
})Alternatively, move the JSON-LD to a computed ref and call useHead once at the top level of <script setup> with the reactive value—this is the more idiomatic Nuxt pattern.
📝 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.
| // Inject JSON-LD as a <script> tag (works without @nuxtjs/seo) | |
| useHead({ | |
| script: [ | |
| { | |
| type: 'application/ld+json', | |
| innerHTML: JSON.stringify({ | |
| '@context': 'https://schema.org', | |
| ...posting, | |
| }), | |
| }, | |
| ], | |
| }) | |
| // Inject JSON-LD as a <script> tag (works without `@nuxtjs/seo`) | |
| useHead({ | |
| script: [ | |
| { | |
| key: 'job-posting-jsonld', | |
| type: 'application/ld+json', | |
| innerHTML: JSON.stringify({ | |
| '@context': 'https://schema.org', | |
| ...posting, | |
| }), | |
| }, | |
| ], | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/pages/jobs/`[slug]/index.vue around lines 147 - 158, The JSON-LD script
injected via useHead is missing a deduplication key, so repeated watchEffect
runs append duplicate <script type="application/ld+json"> tags; update the
script entry passed to useHead (the object in the script array where innerHTML:
JSON.stringify({ '@context': 'https://schema.org', ...posting })) to include a
unique key (e.g., use posting.id or a fixed 'job-jsonld' key) so Nuxt can
dedupe, or alternatively compute the JSON-LD in a computed ref and call useHead
once at top-level in the <script setup>.
- Added @nuxtjs/mdc version 0.20.1 - Added @tailwindcss/typography version 0.5.19
There was a problem hiding this comment.
🧹 Nitpick comments (2)
app/pages/index.vue (2)
4-5: Avoid reading the same session in both the page and the navbar.Line 5 and
app/components/PublicNavBar.vue:1-79both fetch the session to drive adjacent CTAs. Passing the page-level session intoPublicNavBar(or lifting both consumers onto one shared composable) keeps auth state single-owned and avoids split fetch/render logic on/.Also applies to: 25-25
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/pages/index.vue` around lines 4 - 5, The page currently calls authClient.useSession() to get the session while PublicNavBar.vue also independently fetches the session, causing duplicated reads and split state; refactor so the page (where const { data: session } = await authClient.useSession(useFetch) is used) owns the session and pass that session into PublicNavBar as a prop (or alternatively extract a shared composable that both consume) and remove the redundant authClient.useSession call from PublicNavBar.vue so both CTAs use the single source of truth.
70-80: Use list markup for the pillar cards.This is a three-item feature list. Switching the wrapper/items to
<ul>/<li>keeps the layout the same and gives screen readers proper grouping and item counts.♿ Minimal semantic tweak
- <div class="hero-animate hero-delay-4 mx-auto mt-28 grid max-w-3xl gap-4 sm:grid-cols-3"> - <div + <ul class="hero-animate hero-delay-4 mx-auto mt-28 grid max-w-3xl gap-4 sm:grid-cols-3"> + <li v-for="pillar in pillars" :key="pillar.label" class="bento-card relative rounded-xl p-6" > <component :is="pillar.icon" class="mb-4 h-5 w-5 text-brand-400" /> <h2 class="text-[15px] font-semibold text-white">{{ pillar.label }}</h2> <p class="mt-1.5 text-[13px] leading-relaxed text-surface-400">{{ pillar.desc }}</p> - </div> - </div> + </li> + </ul>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/pages/index.vue` around lines 70 - 80, The pillar cards are rendered as plain divs but should be semantic list items; change the outer container element that currently uses <div class="hero-animate ..."> to a <ul> while keeping the same classes, and change each repeated <div v-for="pillar in pillars" :key="pillar.label" class="bento-card ..."> to an <li> with the same classes and the v-for/:key moved to the <li>, keeping the <component :is="pillar.icon" ... />, <h2>{{ pillar.label }}</h2>, and <p>{{ pillar.desc }}</p> intact so the visual layout and classes (hero-animate, bento-card, etc.) are preserved while providing proper semantic grouping for the pillars array.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/pages/index.vue`:
- Around line 4-5: The page currently calls authClient.useSession() to get the
session while PublicNavBar.vue also independently fetches the session, causing
duplicated reads and split state; refactor so the page (where const { data:
session } = await authClient.useSession(useFetch) is used) owns the session and
pass that session into PublicNavBar as a prop (or alternatively extract a shared
composable that both consume) and remove the redundant authClient.useSession
call from PublicNavBar.vue so both CTAs use the single source of truth.
- Around line 70-80: The pillar cards are rendered as plain divs but should be
semantic list items; change the outer container element that currently uses <div
class="hero-animate ..."> to a <ul> while keeping the same classes, and change
each repeated <div v-for="pillar in pillars" :key="pillar.label"
class="bento-card ..."> to an <li> with the same classes and the v-for/:key
moved to the <li>, keeping the <component :is="pillar.icon" ... />, <h2>{{
pillar.label }}</h2>, and <p>{{ pillar.desc }}</p> intact so the visual layout
and classes (hero-animate, bento-card, etc.) are preserved while providing
proper semantic grouping for the pillars array.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ff8dd862-afc4-4265-b9c9-150522ae80e0
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
app/pages/index.vuenuxt.config.tspackage.json
💤 Files with no reviewable changes (1)
- package.json
🚧 Files skipped from review as they are similar to previous changes (1)
- nuxt.config.ts
Remove blog, docs, catalog, roadmap pages and content. Remove @nuxt/content, @nuxtjs/seo, @nuxtjs/mdc, @tailwindcss/typography deps. Replace useSchemaOrg with manual JSON-LD in job detail page. Simplify PublicNavBar for self-hosters. Add redirect index.vue (marketing layer overrides this).
Summary
Type of change
Validation
DCO
Signed-off-by) viagit commit -sSummary by CodeRabbit
Refactor
Chores