mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-16 16:45:07 +00:00
0e3f7d5c68
The tab title suffix came from `import.meta.env.VITE_APP_NAME`, with the starter kit's own `|| 'Laravel'` behind it. Vite resolves that at build time, and a release ships public/build/ already compiled — precisely so nobody downstream needs npm — so whatever the build machine had is frozen for every install that artifact produces. The 2.0.0 zip has `const s2="Laravel"` in app-BoPagLMd.js, and no APP_KEY, APP_NAME or VITE_APP_NAME an operator sets afterwards can reach it (#1619). Swapping the fallback to 'ProjectSend' would fix the reported symptom and leave the mechanism: a name baked at build time, wrong for anyone who renamed their site. The name is already on every page — the shared props carry the site_name setting — so read it from there and drop the build-time variable entirely, .env.example's dead VITE_APP_NAME line included. The root view's own <title> now reads the same shared prop, so the tab does not show one name before hydration and another after on any installation whose administrator renamed the site. Verified in a real browser, which is the only place this is visible — the server-rendered title was always right, and curl never saw the bug. Titles read "Log in - ProjectSend" and, after renaming the site with no rebuild of any kind, "Log in - Acme Files". Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
73 lines
3.8 KiB
PHP
73 lines
3.8 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
@if($page['props']['noindex'] ?? false)
|
|
<meta name="robots" content="noindex">
|
|
@endif
|
|
|
|
{{-- Name only, never the version: this tag is served to anyone
|
|
who asks, and publishing the exact release tells a scanner
|
|
which advisories apply to this installation. What it buys
|
|
is ecosystem visibility — surveys like BuiltWith count
|
|
ProjectSend installs from this and nothing else. --}}
|
|
@if(app(\App\Modules\Platform\Attribution\Attribution::class)->visible())
|
|
<meta name="generator" content="ProjectSend">
|
|
@endif
|
|
|
|
{{-- The same name app.tsx suffixes every page title with, from the
|
|
same place: the site name in the shared props. Taking it from
|
|
APP_NAME instead would show one name in the tab until Inertia
|
|
hydrates and a different one after, on any installation whose
|
|
administrator renamed the site. --}}
|
|
<title inertia>{{ $page['props']['name'] ?? config('app.name', 'ProjectSend') }}</title>
|
|
|
|
{{-- Which cookie holds this installation's CSRF token. Named after
|
|
the installation rather than the framework, so a neighbouring
|
|
Laravel app on the same hostname cannot overwrite it — and
|
|
there is nothing on the client that could work the name out. --}}
|
|
<meta name="xsrf-cookie" content="{{ \App\Http\Middleware\ValidateCsrfToken::cookieName() }}">
|
|
|
|
<link rel="icon" href="/favicon.ico" sizes="48x48">
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
|
|
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
|
<link href="https://fonts.bunny.net/css?family=instrument-sans:400,500,600" rel="stylesheet" />
|
|
|
|
@routes
|
|
@viteReactRefresh
|
|
@php
|
|
// A page component may be shipped by an installed package
|
|
// under vendor/<vendor>/<name>/resources/js/pages/ instead of
|
|
// this app's own resources/js/pages/. This must stay in step
|
|
// with the client-side glob in resources/js/app.tsx — they
|
|
// are two halves of one lookup, and when they disagreed the
|
|
// page built cleanly, type-checked cleanly, and then answered
|
|
// 500 with "Unable to locate file in Vite manifest".
|
|
$pageComponentPath = "resources/js/pages/{$page['component']}.tsx";
|
|
if (! file_exists(base_path($pageComponentPath))) {
|
|
$packageMatch = glob(base_path("vendor/*/*/resources/js/pages/{$page['component']}.tsx"))[0] ?? null;
|
|
if ($packageMatch !== null) {
|
|
$pageComponentPath = ltrim(str_replace(base_path(), '', $packageMatch), '/');
|
|
}
|
|
}
|
|
@endphp
|
|
@vite(['resources/js/app.tsx', $pageComponentPath])
|
|
@inertiaHead
|
|
|
|
{{-- Operator-authored snippets (Community only). Raw by design —
|
|
see CustomAssetsBridge, which returns '' unless the edition
|
|
grants the capability and the module is actually installed.
|
|
This is the one root view for all three surfaces (public,
|
|
portal, staff), so it is the only place they need wiring. --}}
|
|
{!! app(\App\Modules\Platform\CustomAssets\CustomAssetsBridge::class)->render('head') !!}
|
|
</head>
|
|
<body class="font-sans antialiased">
|
|
{!! app(\App\Modules\Platform\CustomAssets\CustomAssetsBridge::class)->render('body_top') !!}
|
|
@inertia
|
|
{!! app(\App\Modules\Platform\CustomAssets\CustomAssetsBridge::class)->render('body_bottom') !!}
|
|
</body>
|
|
</html>
|