recent SSR template or example

Hey there, I'm setting up a solidjs site to be rendered as part of an AWS Lambda function for the first time. The only template-example for a Server-Side-Rendered solid that I could find was this https://github.com/solidjs/solid/tree/main/packages/solid-ssr/examples/ssr but it's 2 years old. Anyone aware of a newer example? The docs have some nice help https://www.solidjs.com/guides/server but i'm more interested into how to configure vite then what to write in my *.jsx files
GitHub
solid/packages/solid-ssr/examples/ssr at main · solidjs/solid
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solid/packages/solid-ssr/examples/ssr at main · solidjs/solid
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
53 Replies
Max
Max2y ago
You could use solid start which facilitates a lot of the SSR stuff https://start.solidjs.com/api/vite
SolidStart Beta Docuentation
SolidStart Beta Documentation
Early release documentation and resources for SolidStart Beta
Max
Max2y ago
think its pretty flexible and there's adapters for aws lambda
Bersaelor
Bersaelor2y ago
Mhmm it seems start solid.js is relatively beta, I tried:
npm init solid@latest
# choose the bare config
npm install
npm init solid@latest
# choose the bare config
npm install
and then got
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: solidtest@undefined
npm ERR! Found: vite@4.1.4
npm ERR! node_modules/vite
npm ERR! dev vite@"^4.1.4" from the root project
npm ERR! peer vite@"*" from solid-start-aws@0.2.22
npm ERR! node_modules/solid-start-aws
npm ERR! peerOptional solid-start-aws@"*" from solid-start@0.2.22
npm ERR! node_modules/solid-start
npm ERR! solid-start@"^0.2.22" from the root project
npm ERR! 8 more (solid-start-aws, solid-start-cloudflare-pages, ...)
npm ERR! 6 more (solid-start-cloudflare-pages, ...)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer vite@"^3.1.8" from solid-start@0.2.22
npm ERR! node_modules/solid-start
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: solidtest@undefined
npm ERR! Found: vite@4.1.4
npm ERR! node_modules/vite
npm ERR! dev vite@"^4.1.4" from the root project
npm ERR! peer vite@"*" from solid-start-aws@0.2.22
npm ERR! node_modules/solid-start-aws
npm ERR! peerOptional solid-start-aws@"*" from solid-start@0.2.22
npm ERR! node_modules/solid-start
npm ERR! solid-start@"^0.2.22" from the root project
npm ERR! 8 more (solid-start-aws, solid-start-cloudflare-pages, ...)
npm ERR! 6 more (solid-start-cloudflare-pages, ...)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer vite@"^3.1.8" from solid-start@0.2.22
npm ERR! node_modules/solid-start
Bersaelor
Bersaelor2y ago
GitHub
Unable to resolve dependency tree , vite@"^4.1.4" vs `vite@"^3.1....
So, I followed the start.solidjs Project setup but didn't get past the third step: npm init solid@latest # chose the bare config npm install and the result was: ❯ npm install npm ERR! code ...
bigmistqke 🌈
yes, I also get same bug with npm, but it succeeds with pnpm
Bersaelor
Bersaelor2y ago
I see, I usually use yarn anyway, haven't installed pnpm yet
bigmistqke 🌈
I also was able to install with yarn it seems to be an npm issue
Bersaelor
Bersaelor2y ago
I didn't want to go very fancy, since the end-goal will be to have this sit in an aws lambda function thats build & minified by esbuild I find so I was using npm, as that seemed more default
bigmistqke 🌈
yes, it's kind of interesting nobody mentioned it before. could it be a sign nobody is using npm anymore?
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Bersaelor
Bersaelor2y ago
the thing is, when I bundle the whole solid.js folder into my lambda function, I use aws sam and when you run sam build It runs npm install for each individual lambda functions folder PS: That said, does anyone know how I can install the adapters that solid-start comes with? ( This one: https://github.com/solidjs/solid-start/tree/main/packages/start-aws )
import solid from "solid-start/vite";
import aws from "solid-start-aws";
import { defineConfig } from "vite";
import solid from "solid-start/vite";
import aws from "solid-start-aws";
import { defineConfig } from "vite";
says Cannot find module 'solid-start-aws' or its corresponding type declarations.
Max
Max2y ago
can just yarn add solid-start-aws https://www.npmjs.com/package/solid-start-aws
npm
solid-start-aws
Adapter for Solid apps that work on AWS Lambda and AWS Lambda@Edge.. Latest version: 0.2.22, last published: 4 days ago. Start using solid-start-aws in your project by running npm i solid-start-aws. There are no other projects in the npm registry using solid-start-aws.
Bersaelor
Bersaelor2y ago
I tried all kind of yarn add solid-start/solid-start-aws and yarn add @solid-start/solid-start-aws but the simplest one I did not
Max
Max2y ago
ahahha that's how it is sometimes xD says very experimental but probably works fine just will likely be changes
Bersaelor
Bersaelor2y ago
mhmm yeah, to get back to the original reason of this thread, I'm wondering whether I should use https://start.solidjs.com/api/vite or just try plain https://www.solidjs.com/guides/server
Max
Max2y ago
guess it depends what kind of project, time etc.. you have. probably nice to see how to do it just with solid and vite. Also cause I think the generalized approach is not so much framework specific so good to learn. Just usual render to string or something then hydrate. I've never set it up so not sure about the specific but I don't think the vite setup changes that much depending on framework, just need to create a client and server bundle https://vitejs.dev/guide/ssr.html#building-for-production. Dev server prob more complex plugins for lambda though https://vite-plugin-ssr.com/aws-lambda
Bersaelor
Bersaelor2y ago
it's really a very small project, just a single page, that represents a single data item from our db. We want to render it Server-side more because to the og-tags, less because it's faster then rendering in the browser. So far I've built two client-rendered solidjs apps and been really happy with them I don't even think we need any hydration. It's just domain.com/id?=12345 and then static pages based on the id
Max
Max2y ago
Nice, maybe then solid-ssr even if not updated in a while could work well. Could use it as part of the hosted app and then generate pages from there, there's some subtleties about SSG though like invalidation and building new pages But then solid start also does that and that's probably the most straightforward and quickest option to try out, so would probably start with that, and it keeps getting better
Bersaelor
Bersaelor2y ago
mhmm, so I already have a version without solid.js running, with some basic html using multiline-template with ${variables}. Since the lambda is behind a cloudfront distribution, CF caches the results as long as I need, and I invalidate them as I need so the invalidation and so forth is easy I don't really save the results in some bucket, like you maybe would with traditional SSG. Just a cached lambda function, that'll respond with the generated page. And in production, each article will only have to be rendered once
Max
Max2y ago
nice seems all setup mostly, maybe just have to switch out whatever render function you're using with multiline templates for solid-ssr's renderStatic function and might just work
Bersaelor
Bersaelor2y ago
yup, I was hoping someone already made that setup in some template and I can just clone it 😉 I guess the key thing is
const html = renderToString(() => <App id={id} event={item} />);
const html = renderToString(() => <App id={id} event={item} />);
in my lambda.ts since < and /> are not valid typescript code. Yet in https://github.com/solidjs/solid/blob/main/packages/solid-ssr/examples/ssr/index.js the example also uses <App url={req.url} /> and I'm still trying to figure out how he made javascript accept those jsx tags aws sam uses esbuild to build the lambda folder into a function, maybe I can use https://how-to.dev/how-to-build-solidjs-application-with-esbuild
Max
Max2y ago
For the SSG example in solid-ssr think this rollup config handles JSX https://github.com/solidjs/solid/blob/main/packages/solid-ssr/examples/ssg/rollup.config.js. Yea if it works just with esbuild. could be nice. If not can always use vite for aws https://vite-plugin-ssr.com/aws-lambda . Then can use same rollup config
Bersaelor
Bersaelor2y ago
thank you. the https://github.com/solidjs/solid/blob/main/packages/solid-ssr/examples/ssg/rollup.config.js link I have open in a tab too, I just haven't figured out how to tell esbuild to use that my template.yml looks like this:
getById:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src/lambda/
Handler: lambda.getByIdHandler
Runtime: nodejs18.x
Architectures:
- x86_64
MemorySize: 512
Timeout: 300
Description: SSR of the player page
Events:
Api:
Type: Api
Properties:
Path: /player
Method: GET
Metadata:
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: "es2020"
Sourcemap: true
EntryPoints:
- lambda.ts
External:
- "@aws-sdk/lib-dynamodb"
- "@aws-sdk/client-dynamodb"
getById:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src/lambda/
Handler: lambda.getByIdHandler
Runtime: nodejs18.x
Architectures:
- x86_64
MemorySize: 512
Timeout: 300
Description: SSR of the player page
Events:
Api:
Type: Api
Properties:
Path: /player
Method: GET
Metadata:
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: "es2020"
Sourcemap: true
EntryPoints:
- lambda.ts
External:
- "@aws-sdk/lib-dynamodb"
- "@aws-sdk/client-dynamodb"
the possible fields for the MetaData entry are described here: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build-typescript.html the template-yml is then built using sam build which compiles the minimal lambda sample. (using npm and esbuild )
Max
Max2y ago
I think best thing would be to use vite so then you can basically use that rollup config since it should just accept it and merge with vite config. Then https://vite-plugin-ssr.com/aws-lambda is basically the server, and I guess you can configure aws sam to build using that, I have no idea about hardly anything AWS but this may help https://github.com/jamesladd/aws-vite-ssr as a starting point
Bersaelor
Bersaelor2y ago
the https://github.com/jamesladd/aws-vite-ssr is interesting, I've been going through that recentlty it runs in two steps, first vite build && vite build --ssr and then uses the serverless framework sls deploy maybe I have to break up my build into two steps: (1) build tsx code to plain js function using vite build --ssr (2) and then use sam build without any typescript/esbuild configs, just accept the js function that vite built as a black box the jamesladd example also just points to the ssr.handler: https://github.com/jamesladd/aws-vite-ssr/blob/main/serverless.yml#L38 I was also looking at this article: https://maxrohde.com/2022/10/16/serverless-react-ssr but he has quite the extensive ESBuild build.ts file, I don't think those options exist in the aws sam template.yml` specs
Max
Max2y ago
I honestly have no idea what server/ssr.handler is pointing to was trying to find out haha
Bersaelor
Bersaelor2y ago
mhmm anyways, I don't think the template.yml has any entry for plugin and in this article https://how-to.dev/how-to-build-solidjs-application-with-esbuild they actually build solid just with esbuild but they use plugins: [solidPlugin()], when I use https://start.solidjs.com/api/vite with
export default defineConfig({
plugins: [solid({ adapter: aws() })]
});
export default defineConfig({
plugins: [solid({ adapter: aws() })]
});
I can run yarn build inside the solid-start subfolder manually, which runs solid-start build. This then creates a dist folder with a server/index.mjs single file maybe I can import the dist/server/index.mjs into my lambda.ts so I can use it to generate the html
Max
Max2y ago
are you using solid-start then over solid-ssr ? probably best if its newer and offer same things and more
Max
Max2y ago
Another option eventually if all this starts to become over complicated is to change from aws, something like cloudflare pages seems good for all these things, and there's even adapters etc to simplify some of the process https://blog.cloudflare.com/pages-full-stack-frameworks/. Can see the solid section
The Cloudflare Blog
Server-side render full stack applications with Pages Functions
Page Functions are now out of beta, bringing the ability to add dynamic server-side rendering to your applications. Pages makes it easy to deploy applications built using all the major frameworks.
Bersaelor
Bersaelor2y ago
I don't know, I have sub-folders with all of them 😄 so the server/index.mjs looks actually much bigger then what I need, 24000 lines of code with export:
async function handler(event) {
const { requestContext } = event;
const response = await entryServer({
request: createRequest(event),
clientAddress:
requestContext.identity?.sourceIp
?? requestContext.http?.sourceIp,
locals: {},
env: { manifest },
});

const headers = {};
for (const [name, value] of response.headers) {
headers[name] = value;
}
if (response.headers.has('set-cookie')) {
const header = /** @type {string} */ (response.headers.get('set-cookie'));
// @ts-expect-error
headers['set-cookie'] = setCookieExports.splitCookiesString(header);
}

return {
statusCode: response.status,
headers: headers,
body: await response.text(),
};
}
export { handler };
async function handler(event) {
const { requestContext } = event;
const response = await entryServer({
request: createRequest(event),
clientAddress:
requestContext.identity?.sourceIp
?? requestContext.http?.sourceIp,
locals: {},
env: { manifest },
});

const headers = {};
for (const [name, value] of response.headers) {
headers[name] = value;
}
if (response.headers.has('set-cookie')) {
const header = /** @type {string} */ (response.headers.get('set-cookie'));
// @ts-expect-error
headers['set-cookie'] = setCookieExports.splitCookiesString(header);
}

return {
statusCode: response.status,
headers: headers,
body: await response.text(),
};
}
export { handler };
this looks very much like a typical lambda-method-handler which is what I already have, not what I need what I want, is a function, like:
import pageRanderer from "solidjs/web"

pageRenderer: (data: DataObject) => string
import pageRanderer from "solidjs/web"

pageRenderer: (data: DataObject) => string
and of course
const html = renderToString(() => <App id={id} event={item} />);
const html = renderToString(() => <App id={id} event={item} />);
doesn't work, because that uses < and /> so, what I need is a way of building the tsx
import { renderToString } from "solid-js/web";
import App from './site/src/App';

const pageRenderer = (data: {id: string, item: string}) => {
const html = renderToString(() => <App id={data.id} event={data.item} />);
return html
}
export pagerenderer
import { renderToString } from "solid-js/web";
import App from './site/src/App';

const pageRenderer = (data: {id: string, item: string}) => {
const html = renderToString(() => <App id={data.id} event={data.item} />);
return html
}
export pagerenderer
into some plain minified js I guess
Max
Max2y ago
Yea I guess that's all aws config if you can have multiple steps
Bersaelor
Bersaelor2y ago
thank you @maxoucsgo having someone to discuss this with
Max
Max2y ago
but I have no idea about aws but guess should all be possible
Bersaelor
Bersaelor2y ago
well, I guess we can ignore the aws part because that I have covered
Max
Max2y ago
np man good to see what's going on what people are up to , I learn something to But the entry point is still all in the aws config .toml file right?
Bersaelor
Bersaelor2y ago
so, I don't think I really need solid-start since it really wants to create some kind of server yes, but I already have a setup that returns pages so that all works fine the problem is, creating a larger page in typescript from scratch is not as nice is having a framework like solid/react or vue
Max
Max2y ago
Yes i think for the AWS approach https://github.com/solidjs/solid/tree/main/packages/solid-ssr should be better option
GitHub
solid/packages/solid-ssr at main · solidjs/solid
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solid/packages/solid-ssr at main · solidjs/solid
Max
Max2y ago
not solid-start
Bersaelor
Bersaelor2y ago
atm, I just do
const html = `
<html>
<head>
<title>${item.title}</title>
// lots of meta tags
</head>
<body>
<h3>${item.title}</h3>
<audio controls>
<source src="${audioURL}" type="audio/mpeg">
</audio>
</body>
</html>
`,
const html = `
<html>
<head>
<title>${item.title}</title>
// lots of meta tags
</head>
<body>
<h3>${item.title}</h3>
<audio controls>
<source src="${audioURL}" type="audio/mpeg">
</audio>
</body>
</html>
`,
without the styles etc I guess my problem is that I've been used to just use create-react-app or vite build and never had to worry what happens inside of those and now, I don't need all the serving parts, I just need to convert the App.tsx to a static string respectyively, build const html = renderToString(() => <App id={id} event={item} />); into a minified js method
Max
Max2y ago
Yea I really also don't really do well with all the devops deployment stuff That's why I mentioned cloudflare pages cause it takes care of that But if you are able and know how to have 2 steps in the AWS sam config then should be possible Would not even solid-ssr package cause I think it just uses renderToStringAsync
Bersaelor
Bersaelor2y ago
I just need to find out how to import the renderToString into my lambda.ts maybe I'll start a new thread with the new starting point, with our boiled down example
Max
Max2y ago
or somehow pass the result of it to lambda, or call it from lambda somehow Yea probably a good idea, can even ask somewhere more general, because I guess the problem right now can be abstract from solid so might get better answers too I would think that https://vite-plugin-ssr.com/aws-lambda is for now the best reference still
Bersaelor
Bersaelor2y ago
the problem is that what that generates is a lambda-function, which accepts an aws-lambda event and returns the complete response I don't need all the server parts I think , If I could build the contents of this exampel here, I'd be happy: https://github.com/solidjs/solid/tree/main/packages/solid-ssr/examples/ssg the problem is I'm not sure how to work with this example, because it doesn't contain any package.json ah, that is here https://github.com/solidjs/solid/blob/main/packages/solid-ssr/package.json#L23 so it does rollup -c examples/ssr/rollup.config.js @maxoucsgo maybe I'm getting closer ? https://discord.com/channels/722131463138705510/1080525441296781403/1080534597164605540
Max
Max2y ago
yea nice so it's setup to compile jsx?
Max
Max2y ago
npm
@rollup/plugin-typescript
Seamless integration between Rollup and TypeScript.. Latest version: 11.0.0, last published: 2 months ago. Start using @rollup/plugin-typescript in your project by running npm i @rollup/plugin-typescript. There are 836 other projects in the npm registry using @rollup/plugin-typescript.
Bersaelor
Bersaelor2y ago
yeah, adding that helped a little, now I have:
import nodeResolve from "@rollup/plugin-node-resolve";
import common from "@rollup/plugin-commonjs";
import babel from "@rollup/plugin-babel";
import typescript from '@rollup/plugin-typescript';

export default [
{
input: "index.tsx",
output: [
{
dir: "/lib",
exports: "auto",
format: "cjs"
}
],
external: ["solid-js", "solid-js/web"],
plugins: [
typescript(),
nodeResolve({ preferBuiltins: true, exportConditions: ["solid", "node"] }),
babel({
babelHelpers: "bundled",
presets: [["solid", { generate: "ssr", hydratable: true }]]
}),
common()
]
}
];
import nodeResolve from "@rollup/plugin-node-resolve";
import common from "@rollup/plugin-commonjs";
import babel from "@rollup/plugin-babel";
import typescript from '@rollup/plugin-typescript';

export default [
{
input: "index.tsx",
output: [
{
dir: "/lib",
exports: "auto",
format: "cjs"
}
],
external: ["solid-js", "solid-js/web"],
plugins: [
typescript(),
nodeResolve({ preferBuiltins: true, exportConditions: ["solid", "node"] }),
babel({
babelHelpers: "bundled",
presets: [["solid", { generate: "ssr", hydratable: true }]]
}),
common()
]
}
];
as a modified version of https://github.com/solidjs/solid/blob/main/packages/solid-ssr/examples/ssg/rollup.config.js If I forgo all typescript, and just run with plain js, it actually seems to start working, looks like a good track
Max
Max2y ago
yea nice, if its quite simple app then really dont need typescript
Bersaelor
Bersaelor2y ago
I dunno, I really love typescript though 😄 you know, I just deleted an import, expecting all the lines that need it to turn red and ... nothing... because no more typescript
Max
Max2y ago
ahhaha same havent made anythin without typescript since 5 years typescript plugin should just transpile it though
Bersaelor
Bersaelor2y ago
I think it's less the typescript then the jsx because I also had to rename my App.jsx to App.js for it to import successfully With the x I get
Error: Could not resolve '../site-js/src/App' from index.js
the solid-ssr example https://github.com/solidjs/solid/tree/main/packages/solid-ssr/examples/shared/src/components also has no jsx only js
Max
Max2y ago
Yea I think with the input output fields it can get a bit confusing, bit trial and error unless you know very well whats happening. But babel should take care of JSX with preset solid.
Bersaelor
Bersaelor2y ago
I know, thats what Ithought too. Will try more tomorrow
Bersaelor
Bersaelor2y ago
i setup a minimal example so we have something tangible to talk about https://github.com/Bersaelor/solid-rollup-aws-lambda
GitHub
GitHub - Bersaelor/solid-rollup-aws-lambda: Using solid.js to serve...
Using solid.js to server-side-render html in a serverless environment - GitHub - Bersaelor/solid-rollup-aws-lambda: Using solid.js to server-side-render html in a serverless environment
Want results from more Discord servers?
Add your server
More Posts