S
SolidJS2mo ago
Subham

Dynamic meta <Title> not updated on routes Solid-start SSR: false

app.config.js import { defineConfig } from "@solidjs/start/config"; export default defineConfig({ ssr: false, server: { preset: "cloudflare_pages" }, }); i searched on chatgpt about my issue as a response The issue you're facing arises because you have disabled Server-Side Rendering (SSR) in your app.config.js with the ssr: false setting. SolidStart uses SSR to inject the meta tags dynamically into the HTML when the server renders a page. By disabling SSR, the meta tags defined in individual components like About.jsx are not rendered at the server level and thus don't appear in the page's initial HTML. i got this... so now how can i fix this problem ? It would be great if there was a more seamless way to ensure that client-only code is either automatically deferred or conditionally executed, without requiring manual checks with onMount or isServer. Is there a recommended approach or potential solution to address this issue more effectively in SolidJS, especially when working with components that require SSR but also need to handle client-specific logic?
6 Replies
peerreynders
peerreynders2mo ago
Given how little information (and of varying quality) is available on Solid that LLMs can be trained with probably limits the usefulness of their responses. It seems you are saying the <Title /> works with SSR but stops working once you disable it. That seems surprising; typically issues with meta arise for the SSR case. Essentially during CSR a <Title /> component communicates with the <MetaProvider /> at the top level application layout which then propagates that information to the necessary elements in the document header. So the MetaProvider exists at the application layout level just inside the Router but above any Route so that route component( layout)s and their nested components can propagate their meta information needs to the MetaProvider which then takes care of the rest. The point being is that solidjs/meta is designed around client-side rendering, so a mechanism by which turning off SSR would break meta is difficult to imagine—suggesting that something entirely different is going on.
GitHub
solid-start/examples/basic/src/app.tsx at 426644e81c6e31da85c1a86d0...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
Subham
SubhamOP2mo ago
I'm encountering an issue with setting <Title> and <Meta> tags in my SolidJS application. Here's the situation: I have an entry-server.jsx file where the meta tags and title set globally (within the MetaProvider) reflect correctly across all pages. However, when I attempt to set individual titles and meta tags using <Title> and <Meta> inside my page components, they don't apply. Specifically: The <Title> and <Meta> components are used inside pages wrapped by the MetaProvider in my App.jsx. Despite this setup, the titles and meta tags specific to individual pages do not show up in the "View Page Source." I've confirmed that the MetaProvider wraps my entire application, as suggested in the documentation. Is there something I'm missing in my setup, or could there be an issue with how the MetaProvider works for individual routes when SSR is disabled? Any guidance or insights would be much appreciated. Thank you!
No description
Subham
SubhamOP2mo ago
Here is my routes
import "./app.css";
import { gsap } from "gsap";
import { Route, Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import Footer from "./components/footer";
import ChatbotLoader from "./components/chatbot/chat";
import LanguageProvider from "./components/translation/langProvider";

import { ErrorBoundary, Suspense, onMount } from "solid-js";
import { MetaProvider } from "@solidjs/meta";

const LoadingSpinner = () => {
return (
<div class="flex justify-center items-center min-h-screen w-full text-xl font-bold text-white">
<span class="loader"></span>
</div>
);
};

export default function App() {
const handleRefresh = () => window.location.reload();
return (
<LanguageProvider>
<ErrorBoundary
fallback={(err) => {
if (err.message === "Unknown error") {
handleRefresh();
}
}}
>
<Router
root={(props) => (
<MetaProvider>
<div id="main">
<Suspense>
{props.children}
</Suspense>
<Footer />
</div>
</MetaProvider>
)}
>
<Route path="/blog/:id" component={BlogSlug} />
<Route path="/faq" component={Faq} />
<Route path="/refunds" component={Refund} />
<FileRoutes />
</Router>
</ErrorBoundary>
</LanguageProvider>
);
}
import "./app.css";
import { gsap } from "gsap";
import { Route, Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import Footer from "./components/footer";
import ChatbotLoader from "./components/chatbot/chat";
import LanguageProvider from "./components/translation/langProvider";

import { ErrorBoundary, Suspense, onMount } from "solid-js";
import { MetaProvider } from "@solidjs/meta";

const LoadingSpinner = () => {
return (
<div class="flex justify-center items-center min-h-screen w-full text-xl font-bold text-white">
<span class="loader"></span>
</div>
);
};

export default function App() {
const handleRefresh = () => window.location.reload();
return (
<LanguageProvider>
<ErrorBoundary
fallback={(err) => {
if (err.message === "Unknown error") {
handleRefresh();
}
}}
>
<Router
root={(props) => (
<MetaProvider>
<div id="main">
<Suspense>
{props.children}
</Suspense>
<Footer />
</div>
</MetaProvider>
)}
>
<Route path="/blog/:id" component={BlogSlug} />
<Route path="/faq" component={Faq} />
<Route path="/refunds" component={Refund} />
<FileRoutes />
</Router>
</ErrorBoundary>
</LanguageProvider>
);
}
peerreynders
peerreynders2mo ago
I have an entry-server.jsx file where the meta tags and title set globally (within the MetaProvider) reflect correctly across all pages.
I'm not familiar with MetaProvider appearing in entry-server.tsx. The basic template uses solidjs/meta and the entry-server.tsx looks like this:
// @refresh reload
import { createHandler, StartServer } from '@solidjs/start/server';

export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
));
// @refresh reload
import { createHandler, StartServer } from '@solidjs/start/server';

export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
));
There is no trace of MetaProvider but metas SSR contributions are injected during SSR via the assets argument. So I would assume that any meta-type tags appearing explicitly in the server-entry.tsx are permanent and not under the control of solidjs/meta. If you inspect the <head> tag of https://strello.netlify.app/login you will notice that there is a <!-- xs --> tag. I suspect that only the meta tags that follow that node are controlled by solidjs/meta; the ones that proceed it are permanent, out of reach of solidjs/meta.
GitHub
solid-start/examples/basic/src/entry-server.tsx at 426644e81c6e31da...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
peerreynders
peerreynders2mo ago
Setting up meta tags globally that are also under solidjs/meta control has to happen in the app.tsx as described in the documentation:
export default function App() {
return (
<Router
root={(props) => (
<MetaProvider>
<Title>SolidStart - Basic</Title>
<a href="/">Index</a>
<a href="/about">About</a>
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
);
}
export default function App() {
return (
<Router
root={(props) => (
<MetaProvider>
<Title>SolidStart - Basic</Title>
<a href="/">Index</a>
<a href="/about">About</a>
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
);
}
Here <Title /> nested directly under MetaProvider serves as the default title for all routes. However anything within props.children can override that default.
GitHub
solid-start/examples/basic/src/app.tsx at 426644e81c6e31da85c1a86d0...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
peerreynders
peerreynders2mo ago
As per HTML spec a page should only have one <title> tag (and the browser will only pay attention to the first one if there are more). So if there already is a <title> in your entry-server.tsx there is little solidjs/meta can do about it.

Did you find this page helpful?