Skip to content

feat: show document title for Project detail pages#2091

Open
blfpd wants to merge 1 commit intogetarcaneapp:mainfrom
blfpd:feat/head-title
Open

feat: show document title for Project detail pages#2091
blfpd wants to merge 1 commit intogetarcaneapp:mainfrom
blfpd:feat/head-title

Conversation

@blfpd
Copy link
Contributor

@blfpd blfpd commented Mar 17, 2026

Checklist

  • This PR is not opened from my fork’s main branch

What This PR Implements

Show document.head title of Project detail pages

Fixes: #2090

Changes Made

  • Add a +layout.svelte under /(app)/projects/

Testing Done

  • Development environment started: ./scripts/development/dev.sh start
  • Frontend verified at http://localhost:3000
  • Backend verified at http://localhost:3552
  • Manual testing completed (describe):
  • No linting errors (e.g., just lint all)
  • Backend tests pass: just test backend

AI Tool Used (if applicable)

no

Additional Context

See #2090

Disclaimer Greptiles Reviews use AI, make sure to check over its work.

To better help train Greptile on our codebase, if the comment is useful and valid Like the comment, if its not helpful or invalid Dislike

To have Greptile Re-Review the changes, mention greptileai.

Greptile Summary

This PR introduces a new +layout.svelte at the (app)/projects/ level to set a dynamic <svelte:head><title> for project pages, and adds a Playwright test asserting the title on the new-project page.

  • Layout placement — placing the layout at (app)/projects/ causes it to wrap /projects (list), /projects/new, and /projects/[projectId] alike. On the list page page.data.project is always undefined, so the title permanently reads "Arcane | Projects | My New Project" (the placeholder), which is misleading.
  • || vs ??page.data?.project?.name || m.compose_project_name_placeholder() treats an empty-string project name as falsy and falls back to the placeholder; ?? would be the correct operator here.
  • Test scope — the new test ('should have a head title') lives in the New Compose Project Page describe block, which is always on /projects/new where page.data.project is undefined. The test will pass because it asserts the placeholder value, but it does not verify that the detail page (/projects/[projectId]) shows the actual project name — the stated goal of the PR.
  • The $derived reactive declarations and {@render children()} usage are idiomatic Svelte 5 patterns.

Confidence Score: 3/5

  • The PR achieves its goal on the detail page but introduces an unintended side-effect on the projects list page and lacks a meaningful title test for the detail page.
  • The layout scope is broader than intended — /projects (list page) will permanently display the placeholder "My New Project" in the document title. The || operator also silently swallows empty-string project names. The new test passes but only validates the fallback path, leaving the detail-page title (the PR's stated goal) without coverage. These issues lower the confidence from an otherwise straightforward change.
  • frontend/src/routes/(app)/projects/+layout.svelte — layout placement and || operator need attention.

Important Files Changed

Filename Overview
frontend/src/routes/(app)/projects/+layout.svelte Adds a shared layout that derives a <title> from page.data.project.name with a placeholder fallback; because it is placed at the (app)/projects/ level it applies to all three sub-routes (/projects, /projects/new, /projects/[projectId]), producing a misleading "My New Project" title on the projects list page, and uses `
tests/spec/project.spec.ts Adds a title assertion test inside the "New Compose Project Page" describe block; the test correctly matches the placeholder fallback ("My New Project") and will pass, but it only validates the fallback behavior on /projects/new rather than an actual project name on the detail page, leaving the PR's primary goal untested.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Browser navigates to /projects/*] --> B{Which route?}
    B -->|/projects| C[page.data = projects, counts]
    B -->|/projects/new| D[page.data = templates, envTemplate]
    B -->|/projects/projectId| E[page.data = project, editorState]

    C --> F{page.data?.project?.name}
    D --> F
    E --> F

    F -->|undefined| G[Fallback: 'My New Project']
    F -->|empty string via OR| G
    F -->|real name| H[Use project.name]

    G --> I["Title: 'Arcane | Projects | My New Project'"]
    H --> J["Title: 'Arcane | Projects | actual-name'"]

    I -->|⚠️ misleading on /projects list| K[svelte:head title set]
    I -->|✓ correct on /projects/new| K
    J -->|✓ correct on detail page| K
Loading

Last reviewed commit: b495010

Context used:

  • Rule used - What: Avoid updating $state inside $effect blo... (source)

@blfpd blfpd requested a review from a team March 17, 2026 13:32
@blfpd blfpd force-pushed the feat/head-title branch from 5791f4c to b495010 Compare March 17, 2026 13:52
@blfpd
Copy link
Contributor Author

blfpd commented Mar 17, 2026

@greptileai Redo the review with current push-forced commit

@blfpd blfpd force-pushed the feat/head-title branch from b495010 to b92e70a Compare March 17, 2026 15:01
@blfpd blfpd force-pushed the feat/head-title branch from b92e70a to 9d5a17e Compare March 17, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

⚡️ Feature: Show document.head title of Project detail pages

1 participant