github varabyte/kobweb v0.20.4

latest releases: v0.24.0, v0.23.3, v0.23.2...
15 months ago

This release includes several miscellaneous fixes.

Perhaps one of the more interesting new features is that you can opt in to automatically convert external resource links declared in your <head> block into locally hosted files, which gets performed at build time.

This can allow users to use a feature like Silk's font awesome icons or add a link into their build script to some external URL (e.g. for a font, script, or stylesheet) but then ask Kobweb automaticaly download and locally host it.

Important

Planning to upgrade? Review instructions in the README.

Changes

Frontend

  • Fixed SVG icon clipping that could occur due to rounding.
  • You are now allowed to create a site without a root route (i.e. "/").
    • This was supposed to be a warning before but became an error at one point due to a refactoring.
  • navigateTo when called on your current site's domain now behaves as a hybrid internal / external route.
    • e.g. navigateTo("https://yoursite.com/about") instead of just navigateTo("/about")
    • By external, it basically makes a new fetch request to a server (while internal navigation happens all on the client).
    • By internal, it uses the "open internal links" strategy, which opens the target page in place instead of in a new tab.
    • If you have a base path configured for your site, it will not be applied in this case.
  • Fixed an issue where tooltips could reopen after switching tabs.
    • The results seem like they might be browser / OS dependent so we are continuing to investigate this into the next release.

Silk

  • Add new OutlinedFilledCalloutVariant for callouts.
    • This gives callouts a solid fill color look with a thin outline border.

Backend

  • Disable caching for CSS files when in dev mode, fixing live reload issues.
    • This would hit users who hosted raw CSS files in their resources/public folders and edited them during development.
  • Added helpful, kotlinx serialization aware helper methods to the Request and Response classes.
    • i.e. request.readBody<SomeValue>() and response.setBody<SomeValue>(someValue).
  • Servers now log any declared CORS configurations, which can be helpful in debugging CORS issues.
    • We added this after a user put CORS values in their .kobweb/conf.yaml but with incorrect indentation, so the server wasn't finding them and they didn't know.

Gradle

  • Add build script support for intercept URLs found in <head> elements, especially useful for converting CDNs into self-hosted resources.
    • See the Notes section for more details.
  • Add a new kobwebSiteRoutes extension property, allowing you to query all routes declared in your site.
    • See the Notes section for more details.
  • Fixed an issue where live reloading would break if you ran the raw Gradle kobwebStart -t command outside of the site directory.

Markdown

  • You can now specify an alternate callout variant to use inside the callout.
    > [!NOTE {variant = com.varabyte.kobweb.silk.components.display.OutlinedCalloutVariant}]
    > Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    • See the README for more information about callouts in Markdown.

Notes

Intercepting URLs and self hosting

kobweb {
  app {
    index {
      interceptUrls { 
        enableSelfHosting()
      }
   }
}

Many sites use a convenient solution for referencing external resources in their site through content delivery network, or CDN, links. Installation instructions for many web resources often recommend them as an option.

Unfortunately, this easy solution may result in a site not being GDPR compliant.

Note

Further discussion about GDPR is far outside the scope of these release notes, but if you're interested, you may want to review links like https://en.wikipedia.org/wiki/Content_delivery_network#Security_and_privacy and find blog posts discussing the topic.

A common way to deal with GDPR compliance is by self hosting resources yourself. However, there is no one-size-fits-all solution.

Kobweb wants to allow users to choose whatever solution works best for their needs, so in this release, we think we've found an easy way to support both -- by providing support for intercepting URLs found in <head> elements.

You add URL interception rules through the interceptUrls block. Essentially, if you have a head element that references an external link, you can use URL interception to detect them and replace them with a new value, often a local path on your own server.

Note

Such links might come from Kobweb libraries that you add as dependencies -- for example, the Kotlin Bootstrap library adds a few links of its own.

If you call enableSelfHosting() inside your interceptUrls block, Kobweb will do all of this for you.

For example, the kobweb create examples/opengl project has the following code in its build script:

kobweb {
    app {
        index {
            head.add {
                script {
                    src = "https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.js"
                }
            }
        }
    }
}

If you add interceptUrls { enableSelfHosting() } to the index block, then when you run and open the project, you'll see that a copy of gl-matrix-min.js was downloaded locally. If you inspect the site in the network tab of your dev tools and look at where the gl-matrix-min.js is hosted, you'll see something like: http://yoursite.com/_kobweb/self-host/cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.js

If you want more manual control, the interceptUrls block also provides a replace method:

interceptUrls {
   replace("https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.js", "/gl-matrix/script.js")
}

at which point, you'd be on the hook to add /src/jsMain/resources/public/gl-matrix/script.js to your project yourself.

In general, CDN links offer quite a few advantages, so you shouldn't replace them just because it is easy to do so -- you'll increase your bandwidth bill, while you'll also likely serve those files much slower than a CDN would have. But at least now Kobweb can support projects that decide to make this change.

kobwebSiteRoutes

Querying the list of registered site routes in your Kobweb build script can be useful, for example letting you programmatically create a sitemap.

Using kobwebSiteRoutes in a custom task looks like this:

tasks.register("createSitemap") {
     // fetch in configuration phase
     val routesProvider: Provider<List<String>> = kobwebSiteRoutes 
     inputs.property("routes", routesProvider)
     doLast {
         val routes = routesProvider.get() // query in execution phase
         val sitemapStr = buildList {
             routes.forEach { route -> add("https://yoursite.com$route") }
         }.joinToString("\n")
         // save sitemapStr to disk...
     }
 }

Important

Note in the above example that the kobwebSiteRoutes property is queried during the task configuration phase and then its returned value is queried during the task execution phase. If you don't do this, Gradle may complain at you for invalidating cache requirements.


Full Changelog: v0.20.3...v0.20.4

Don't miss a new kobweb release

NewReleases is sending notifications on new releases.