Xojo Web & SEO

Just wondering if anyone can point me in the right direction on even where to start with SEO in a Xojo Web app. It doesn’t seem like search engines are able to extract any content to index my apps at all. Bing even warned me that there are zero words on the page, and there are definitely words on the page.

I acknowledge that one of the challenges is that different WebPages of the app have no “url” that can be linked to, but I’ve coded for that in HandleURL to fudge it with cookies and redirects. Search engines don’t seem to like that at all.

I see SEO is on Xojo’s roadmap but that could be years away and I’m wondering what we can do until then. Has anyone else approached this?

1 Like

Starting in 2026r1, there are a few improvements focusing SEO:

  1. You can call WebPage.Show directly from the HandleURL event, to allow having real URLs on your web app
  2. WebLabel default HTML element is <p> now, instead of <label>, and you can also use others, like <h1> for headings

Take a look at this sample project:
handleurl-webpage.xojo_binary_project.zip (14.1 KB)

7 Likes

Is there documentation about all the effects of this? To illustrate the first concern that popped into my head, what of the global Session variable?

I skimmed the 2026r1 Web blog post for details but didn’t see this.

In my head that was already covered in my release blog post, but obviously it isn’t :sweat_smile:, I’ll have to write a new one.

Most of the time you should be fine, a Session will be ready for you in paths that aren’t used by the framework itself. You could use it in /foo, but not when the Request.Path is set to a CSS asset URL, for example.

5 Likes

Is there going to be a way to not spin up a session when something comes into HandleUrl?

2 Likes

Thanks for pointing that out. I definitely need to add a way to opt-in (or opt-out) from this feature as it can definitely hurt performance.

The framework won’t be spinning new sessions all the time (it won’t spin a new one when receiving a WebButton.Pressed event, for example), just on certain paths but, still, it might be noticeable for plain HTTP APIs that won’t make any use of it.

4 Likes

Thank you, it definitely will in my experience, but if you only spin up a session if the session cookie is set, that would be an easy thing for the clients to omit.

1 Like

Good, the ability to opt out is needed whenever performance is what is critical, and it often is.

Please make it opt-in so existing projects still work as-is.

3 Likes

Other than performance, is there any other concern?

I’m asking because, after optimizing this (and other somewhat related places), the framework will perform better than previous releases, even when having this portion of code running.

2 Likes

Could better performance be detrimental to something else? :grinning_face:

How about that none of your professional grade users have asked for this.

You’ve known I haven’t wanted this since I caught HEAD requests spinning up sessions. I have users still complaining session count is wrong.

A session should not get created unless the browser executes JavaScript. Now THAT is a change I’d like to see. There literally is no use otherwise.

1 Like

If a Session in a HandleURL instance is not “strictly necessary” then setting the cookies for it could run afoul of consent laws in the EU. Perhaps someone who is more informed about those rules could chime in on this.

But if there’s a difference between with and without session code, that should still be available? Users who don’t want sessions started should still be able to get the boost from your new code.

1 Like

Thanks everyone for the feedback.

What I don’t like is adding a command line parameter or similar just for this, that could be a transient issue (it still adds a ~10% overhead, even after some optimizations). Another option would be adding a parameter (or a WebApplication setting) for configuring the app to be completely headless, for web services.

Some metrics (I’m still working on this):

  • 2025r3.1 could handle around 7800 requests/s (WebPage can’t be loaded from HandleURL)
  • 2026r1.1 sadly dropped to 3530 requests/s (WebPage can be loaded from HandleURL)
  • 2026r2 internal build can handle 10132 requests/s (WebPage can still be loaded from HandleURL, and around 11k requests/s removing the ability to load a WebPage from HandleURL)

Thanks Christian, I’ve double checked and the good news is WebSession objects won’t be sending any cookie back to the browser.

SEO friendly web apps are actually something that is being requested more and more, there are users that just can’t choose Xojo because of it. This thread started with a SEO conversation (which has been derailed a bit). Having to create a WebSession in one specific path in the framework isn’t the end goal, it’s a tradeoff that hopefully could be removed or its impact reduced (which has already been done for r2)

Could you please send me those case numbers or some breadcrumbs to reproduce that issue?

I’m sorry but I have to kindly disagree here. A WebSession has to exist before knowing if the browser can execute JavaScript or not. Part of the long-term SEO goals would be doing some kind of server side rendering for the first page load, then enhance it with JavaScript.

2 Likes

Which is going to be an unnecessary hit for an app that is only a web api.

And I’m not suggesting that you do. But what you could do is make it reliant on a header that only a browser should be sending. For instance, these are commonly used by a browser but not in an API call.

Referer and Origin.

1 Like

Obviously I’m just one voice, but I really do think SEO options are vital for a lot of applications and I can totally see how the lack of them would be a dealbreaker for Xojo Web as a tool. I have built out a project and now am coming to realize that it’s “un-googleable” without implementing a lot of really hacky workarounds.

In regards to the automatic websessions, I agree that it’s unnecessary overhead for API type applications. Obviously some testing would be necessary to see how much penalty it actually incurs in both memory and CPU, but I have several projects that are combinations of both WebPages and API style responses, and it would be nice to be able to spin up a session when needed from HandleURL but not have it be mandatory.

Personally I’d love to see the classic behavior remain, where there is no WebSession created by default but maybe be able to create one with a command in HandleURL and hand it off to a WebPage.

3 Likes

10132 - 11k requests/s is very good and Im happy to hear that.
But, what would happen if 10k different users hit the server in a short time, would the server then fire up 10k individual sessions, one for each of them. How would that hold out? I thought the default maximum was about 2-300 or so. Feels like 10k sessions would kill the server then if that happens. If so I think many of us need a way to avoid that.

1 Like

Just made some tests with 2026R1.1

In HandleUrl I have some rest api with SessionID parameter

Var WSC As New WebSessionContext(SessionID) ,

produces expeption: “WebSessionContexts cannot be created within a running session.”

1 Like

Yup. So anyone who has already done this in their projects is going to have to refactor their projects. That’s what I was forecasting.

2 Likes