auf deutsch language-switchlast updated 2024-02-16 17:04

The idea

Welcome to the website of the freelance software developer Martin Hartnagel. You can contact the freelance software developer by clicking on the green office stapler. Dynamic desktop applications require a broad background knowledge of the frameworks, the components they contain and experience with usability. In addition, each application should work in modern web browsers, behave similarly and look no different.

Single Page Applications (SPA)

If a website loads all pages beforehand, it is far from being a SPA. Loading user-generated content is also not a crucial feature to speak of a SPA. Likewise, responsive behavior is not crucial for being classified as a SPA. If everything only happens on a single page, then you are approaching a SPA. Does this also apply to the areas of documentation, error handling and support requests?

The following areas must be taken into account in most SPA and are often neglected:

  • Routing
  • State management (possibly with SSR)
  • Performance, especially the Core Web Vitals
  • Search engines (SEO)
  • User Experience
  • Login, logout
  • Internationalization
  • Documentation
  • Online help
  • Error handling
  • Support requests
  • Offline behavior
  • Online detection
  • Memory management
  • Caching behavior
  • Update the SPA if browser cache prevents this
  • Data synchronization, export, import and backup
  • DSG-VO critical data

Progressive Web Application (PWA)

A PWA can be installed as an app on a smartphone via the web browser. Building a SPA and app in one saves, above all, costs in development. You also don't need to make the app available in app stores, but then you don't have the advantages of such a marketplace.


Inevitably, you should also deal with the following topics here (in addition to the SPA areas):

  • Create trust (similar to the App Store) regarding security for the end customer
  • Update an installed app to an older version
  • Data synchronization between multiple devices, export, import and backup
  • Marketing (even if it's free, end customers still have to be persuaded to open the SPA on their smartphone)
  • Target devices and behavior when opened on other devices
  • Access to native device functions, partial restrictions on these and from when the app is unusable without essential approvals.
  • Generate Android Package (APK) and still use app stores

Documentation with Markdown

Documentation should be recorded quickly and easy to maintain, require little additional effort and should not require a long training period again even after a long break. Markdown has become the standard here. With Remark and Rehype, the generation of stylish websites with smart additional functions is quick and allows a lot of additional flexibility afterwards. For example, generated tables of contents, linkable headings and automatic keyword linking make reading the documentation much more pleasant - as used here on this website. Markdown can be easily versioned via Git and changes can be easily merged. This cannot necessarily be said about HTML, Word documents or PDF.

An example of how Unified, Remark and Rehype can automatically enrich search terms in Markdown with links:

// ...
import { fromHtml } from 'hast-util-from-html'

const replacements = [
  { s: "React", l: "", t: "React: The library for web and native user interfaces" },
  { s: "Ohrenschmauss Verlag", l: "", t: "Hörbücher im Ohrenschmauss Verlag, Genuss und Spannung für die Ohren" },

const replaceWithLinks = (parent, i, node) => {
  if (['p', 'li', 'td'].includes(parent?.tagName) && node.type === 'text') {
    let v = node.value;
    let changes = false;
    replacements.forEach((r) => {
      if (v.match(r.s)) {
        v = v.replace(r.s, '<a href="'+r.l+'" title="'+r.t+'">'+r.s+'</a>');
        changes = true;
    if (changes) {
      parent.children.splice(i, 1, fromHtml(v, { fragment: true }));
  } else {
    node.children?.forEach((n, i) => replaceWithLinks(node, i, n));

const file = await unified()
  .use(rehypeStringify, { allowDangerousHtml: true })
  .use(() => (tree) => { replaceWithLinks(undefined, 0, tree); })
  .process(`# some title where React and Ohrenschmauss Verlag are left untouched\n\n
  paragraph with React and Ohrenschmauss Verlag automatically replaced links.`);


<h1>some title where React and Ohrenschmauss Verlag are left untouched</h1>
<p>paragraph with <a href="" title="React: The library for web and native user interfaces">React</a> and <a href="" title="Hörbücher im Ohrenschmauss Verlag, Genuss und Spannung für die Ohren">Ohrenschmauss Verlag</a> automatically replaced links.</p>

Give an order

Do you need this expertise in your company? Are you already in the process of implementing something like this and are stuck? Maybe the freelance software developer on this site can help you. Yes, exactly, click on the green office stapler...

^ back to top