Appropriate server-side rendering (or OGP generation per URL)

I am planning to create an SSR site, but given the lack of SSR packages for canisters and the nominal 1 sec response cache at the boundary nodes even with a proprietary implementation, it seems to be difficult at this time to create it fully on-chain.

I’m considering one of the following;

  • Building the front end on Web2 and linking it to the back end on IC.
  • Use SSG, but implement OGP for each URL on IC, and retrieve other data associated with the URL on the client.
  • Attempt SSR on chain.

In reality, edge computing like AWS and Cloudflare are very good in terms of performance and are the best option for customer experience.
However, given the future growth of the IC ecosystem and the importance of distributed infrastructure, I want to consider possible options.

Can you give me your opinion on the best SSR design at this time, assuming that the front end is portable?

(This is not so important, but I will use Rust for both the front and back end.)

1 Like

As far as I know, SSR is not supported. Dynamic URLs are also not supported as every route needs to be certified. I prefer using query parameters.

The above issues might be possible to resolve with certification v2 (?), but I’m really not sure about it and not aware of any activities in that direction.

Personally, I prefer SSG over a simple SPA.

I’m not sure what ‘OGP’ is.

1 Like

Dynamic URLs are also not supported as every route needs to be certified.

I did not grasp this. Are routes certified at deployment?
That would make SSR, etc. impossible. Hoping for future support.

Since it is impractical for this service to perform SSG for all routes, the method to be taken is to use query parameters, but this is also undesirable due to the need for OGP.

OGP (Open Graph protocol) is specified in the html head.meta tag and handles content such as images that are displayed when links are shared on sites such as Twitter and Facebook.
The problem is that OGP crawlers do not execute JavaScript or Wasm after retrieving the html data, so if you want to use individual OGP data for each URL, you need to generate it in advance.

It would be preferable to have OGP data generated for each URL due to the nature of the service, so until these issues are resolved, I will focus on building an external front end.

Thank you.

Yes. At least with certification v1, at build time routes need to be known before uploading static files to the chain.

Not sure with certification v2, maybe @Severin can confirm.

Ah OG tags, gotcha.

Unless Severin brings new light on this, which would probably still implies that you would have to develop your own canister to perform SSR on chain, I would said that building a client side app (with or without pre-rendering) is a safe path.

1 Like

Unless Severin brings new light on this, which would probably still implies that you would have to develop your own canister to perform SSR on chain, I would said that building a client side app (with or without pre-rendering) is a safe path.

Well, just to be sure, is it possible to build proprietary SSR with dynamic routing?
For example, by the basic method of returning text/html according to path for http_request query?

Yes that’s how it already works. You can for sure definitely serve static files -HTML, JS, CSS, images etc. whatever files - for a path.

These files need to be build (locally or in a ci, npm run build) and then uploaded on chain.

When an url is requested, the corresponding file is served. One to one without additional “server” processing and modification to its content.

i.e. a client side app (SPA or SSG) can be hosted on chain.

You can not implement server side rendering (SSR) with certification v1.
You can not build dynamic routes with certification v1.

With certification v2 which I don’t know well, not sure therefore pinging my colleague and once again, even if it would, not sure neither if you would not have to build you own SSR renderer code.

Hope this makes makes. Let me know if not and let’s wait next week to get an answer from Severin about the open question.

1 Like

Yes that’s how it already works. You can for sure definitely serve static files -HTML, JS, CSS, images etc. whatever files - for a path.

I see, that’s how asset canisters work.

When an url is requested, the corresponding file is served. One to one without additional “server” processing and modification to its content.

You can not implement server side rendering (SSR) with certification v1.
You can not build dynamic routes with certification v1.

Thank you for the detailed explanation.
I now have a better understanding of the routing limitations in certification v1.
For the time being, I will follow the certification v2 update while using an external solution.

1 Like

It’s doable, both with v1 and v2, but it may be difficult depending on your response time and security requirements. Just FYI: there’s already discussions happening about deprecating v1, so please go with v2 if you do anything custom

No matter what you do, you probably have to create your own canister for this. There’s two approaches that I can come up with quickly that you can try:

  1. Exclude certain paths/files from certification. You can (certifiedly) say that certain parts (e.g. the response, specific headers) are dynamic and won’t be certified. Of course this makes things less secure but (at least in my opinion) a lot of use cases aren’t that security critical
  2. What one of Kyle’s cool projects does: If you want to serve a dynamic response you can upgrade the query to http_request to an update call. I that update call you can then add your response to the tree of certified responses (and prune outdated ones). Then you can serve this dynamically. Problem: it takes ~2 seconds do do the whole upgrade dance

Happy to go into more detail if you’re interested, but I’ll keep it short-ish so I don’t type a whole essay

Resources:

  • Certification spec
  • Rust certification stuff that I wrote when I implemented v2 for the asset canister. Planned to release it as a separate crate but haven’t gotten around to that. Feel free to copy/past the whole folder
  • Kyle’s certified cache
  • Kyle’s Motoko asset canister, which I suspect uses the certified cache to do some cool things
4 Likes

Thanks for the feedback, Severin. It’s filled with valuable information!

For context, my understanding of SSR is about responding to an HTTP request with an HTML file that is generated on the server side, containing dynamic data computed on the server side, and serving it as quickly as possible. This is why I previously stated that, in my opinion, it’s not possible to achieve this with certification v1.

1 Like

Yes, if you’re not willing to wait for 2 seconds then it’s impossible with v1 since it doesn’t allow certain paths to be excluded

3 Likes

Peter and Severin, thank you for all your advice!
I will review the references and check Severin and Kyle’s code. It may be possible to get sufficient availability by using un-certified SSR pages only for the parts where security is not critical.

Integrating IC into SSR with existing frameworks doesn’t seem easy (dedicated crates and packages could be created), so it will be an afterthought as a work in progress, but I’m glad to know it’s possible. I will report back with any updates.