<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <atom:link href="https://marcusolsson.me/rss.xml" rel="self" type="application/rss+xml" />
        <title><![CDATA[Marcus Olsson – Frilansande webbutvecklare / Artiklar]]></title>
        <link><![CDATA[https://marcusolsson.me/rss.xml]]></link>
        <image>
            <url>https://marcusolsson.se/icons/android-chrome-192x192.png</url>
            <title><![CDATA[Marcus Olsson – Frilansande webbutvecklare / Artiklar]]></title>
            <link><![CDATA[https://marcusolsson.me/rss.xml]]></link>
        </image>
        <description><![CDATA[Marcus Olsson är en frilansande webbutvecklare och webbdesigner i Borås. Erbjuder produktion av webbsidor, applikationer, nyhetsbrev och mycket annat.]]></description>
        <language>sv-SE</language>
        <pubDate>Tue, 24 Feb 2026 20:59:05 +0100</pubDate>

                    <item>
                <title><![CDATA[Blaze – supereffektiva Laravel-komponenter]]></title>
                <link>https://marcusolsson.me/artiklar/blaze-supereffektiva-laravel-komponenter</link>
                <description><![CDATA[<p>Äntligen kan man bygga snabba och effektiva Laravel-appar även när man förlitar sig på återanvändbara &quot;anonyma komponenenter&quot; – tack vare det nya paketet <strong>Blaze</strong> från Caleb Porzio (skaparen av <a href="https://livewire.laravel.com/" target="_blank" rel="noopener">Livewire</a>).</p>
<p>Under de senaste 1-2 veckorna har jag kört varje ny beta-version vid utvecklingen av en ny stor produkt som jag jobbar med. Under den tiden har jag med lätthet kunnat se en reducering av laddningstiden upp till 90-95% vid kompileringen dessa komponenter. Egentligen utan någon som helst konfiguration.</p>
<p>Detta är särskilt tydligt i t.ex. större tabeller när man bygger upp både rader och celler med t.ex.</p>
<pre><code data-theme="dark" data-lang="blade" style='background-color: #24292e; --theme-selection-background: #39414a;'><!-- Syntax highlighted by torchlight.dev --><div><span> 1</span><span>@foreach</span><span>($data </span><span>as</span><span> $datum)</span></div><div><span> 2</span><span>    &lt;</span><span>x-table.row</span><span>&gt;</span></div><div><span> 3</span><span>        &lt;</span><span>x-table.td</span><span>&gt;</span></div><div><span> 4</span><span>            </span><span>{{</span><span> $datum</span><span>-&gt;</span><span>field_1 </span><span>}}</span></div><div><span> 5</span><span>        &lt;/</span><span>x-table.td</span><span>&gt;</span></div><div><span> 6</span><span>        &lt;</span><span>x-table.td</span><span>&gt;</span></div><div><span> 7</span><span>            </span><span>{{</span><span> $datum</span><span>-&gt;</span><span>field_2 </span><span>}}</span></div><div><span> 8</span><span>        &lt;/</span><span>x-table.td</span><span>&gt;</span></div><div><span> 9</span><span>    &lt;/</span><span>x-table.row</span><span>&gt;</span></div><div><span>10</span><span>@endforeach</span></div></code><code data-theme="light" data-lang="blade" style='background-color: #fff; --theme-selection-background: #e2e5e9;'><!-- Syntax highlighted by torchlight.dev --><div><span> 1</span><span>@foreach</span><span>($data </span><span>as</span><span> $datum)</span></div><div><span> 2</span><span>    &lt;</span><span>x-table.row</span><span>&gt;</span></div><div><span> 3</span><span>        &lt;</span><span>x-table.td</span><span>&gt;</span></div><div><span> 4</span><span>            </span><span>{{</span><span> $datum</span><span>-&gt;</span><span>field_1 </span><span>}}</span></div><div><span> 5</span><span>        &lt;/</span><span>x-table.td</span><span>&gt;</span></div><div><span> 6</span><span>        &lt;</span><span>x-table.td</span><span>&gt;</span></div><div><span> 7</span><span>            </span><span>{{</span><span> $datum</span><span>-&gt;</span><span>field_2 </span><span>}}</span></div><div><span> 8</span><span>        &lt;/</span><span>x-table.td</span><span>&gt;</span></div><div><span> 9</span><span>    &lt;/</span><span>x-table.row</span><span>&gt;</span></div><div><span>10</span><span>@endforeach</span></div></code></pre>
<p>De allra flesta buggarna verkar nu vara fixade, och version 1.0 släpptes för bara någon timma sedan. Bör nästintill vara default i varje nytt Laravel-projekt.</p>
<p>In och testa! Läs mer på <a href="https://blazephp.dev/" target="_blank" rel="noopener">blazephp.dev</a>, och läs mer om hur det funkar och eventuella &quot;pitfalls&quot; på <a href="https://github.com/livewire/blaze" target="_blank" rel="noopener">github.com/livewire/blaze</a>.</p>
<p><em>This article, "Blaze – supereffektiva Laravel-komponenter", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/blaze-supereffektiva-laravel-komponenter</guid>
                <pubDate>Tue, 24 Feb 2026 20:59:05 +0100</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Wikipedia fyller 25!]]></title>
                <link>https://marcusolsson.me/artiklar/wikipedia-fyller-25</link>
                <description><![CDATA[<p>Världens uppslagverk <a href="https://www.wikipedia.org/" target="_blank" rel="noopener">Wikipedia</a> har precis fyllt 25 år!</p>
<p>För att fira har Wikimedia Foundation (förvaltarna av Wikipedia) <a href="https://wikipedia25.org/en" target="_blank" rel="noopener">publicerat en jubileumssajt</a> med tillbakablickar, information och statistik över de gångna åren. Väl värt en titt.</p>
<p>Jag själv upptäckte Wikipedia någon gång under sena högstadiet/början av gymnasiet (bör ha varit runt 2003). Men vill minnas att kvalitén var ganska låg och källhänvisningarna var svåra att kontrollera – oftast fick man fortfarande förlita sig på böcker genom skolans bibliotek och uppslagsverk.</p>
<p>Men nu, 2026, är Wikipedia min mest besökta webbsida och förmodligen mest använda iOS-appen (riktigt bra app för övrigt) – har precis som många andra väldigt lätt att halka ner i diverse &quot;rabbit holes&quot; när man har lite dödtid.</p>
<p>Svårt också att säga när man gjorde sin första &quot;edit&quot;, men min nuvarande användare skapade jag 2010, och mina första redigeringar var &quot;Landvetter Airport&quot; på engelska Wikipedia och &quot;Java&quot; (programmeringsspråk) på svenska. Båda i mitten av 2010. Nu för tiden redigerar jag mest när jag upptäcker döda länkar och/eller uppenbara SEO-länkar.</p>
<p><strong>Stort grattis Wikipedia</strong>! Låt oss hoppas på 25 år till, även om kunskap och information inte direkt verkar vara riktigt lika populärt idag som det en gång var.</p>
<p><em>Spana även in de <a href="https://en.wikipedia.org/wiki/Wikipedia:First_100_pages" target="_blank" rel="noopener">100 första sidorna som publicerades</a> på Wikipedia.</em></p>
<p><em>This article, "Wikipedia fyller 25!", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/wikipedia-fyller-25</guid>
                <pubDate>Sat, 17 Jan 2026 08:46:17 +0100</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Orion 1.0]]></title>
                <link>https://marcusolsson.me/artiklar/orion-10</link>
                <description><![CDATA[<p><a href="https://orionbrowser.com/" target="_blank" rel="noopener">Webbläsaren Orion</a> – som jag nämde i <a href="/artiklar/flytta-mail-fran-gmail">ett tidigare inlägg</a> – är nu släppt i som 1.0.</p>
<p>Orion är en väldigt intressant webbläsare, främst då den satsar på helt rätt saker: snabbhet, säkerhet och minus all AI-bloat som verkar hitta in överallt nuförtiden. Dessutom så har den brett stöd för extensions/plugins – i princip alla extensions som du kan köra i Firefox och/eller Chrome och Safari går att installera.</p>
<p>Byggd på Webkit (likt Safari) tillskillnad ifrån Blink som de allra flesta webbläsarna använder (Edge, Chrome och i princip alla dess kloner och &quot;AI webbläsare&quot;).</p>
<p>Väl värt tiden att ladda ner, installera och testa.</p>
<p>Jag körde på Orion under ett par veckor tidigare i år men blev aldrig riktigt van med de devtools:en som ervbjuds i Webkit (kört på Firefox, och nu på sistone LibreWolf de senaste fyra åren).</p>
<p>Det enda egentliga som håller webbläsaren tillbaka just nu är att den är closed source – för de som detta är ett hinder för rekommenderar jag <a href="https://librewolf.net/" target="_blank" rel="noopener">LibreWolf</a> eller att köra <a href="https://webkit.org/" target="_blank" rel="noopener">Webkit</a> direkt (vill även egentligen rekommendera Chromium, men är svårt i dagsläget då Google lägger trackers även i open source-varianten.)</p>
<p>–</p>
<p>Läs mer på <a href="https://orionbrowser.com/" target="_blank" rel="noopener">orionbrowser.com</a> och på <a href="https://blog.kagi.com/orion" target="_blank" rel="noopener">deras blogg</a>.</p>
<p><em>This article, "Orion 1.0", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/orion-10</guid>
                <pubDate>Wed, 26 Nov 2025 22:27:02 +0100</pubDate>
                            </item>
                    <item>
                <title><![CDATA[personnummer.se v2]]></title>
                <link>https://marcusolsson.me/artiklar/personnummerse-v2</link>
                <description><![CDATA[<p>För ett par år sedan så byggde jag <a href="https://personnummer.se/" target="_blank" rel="noopener">personnummer.se</a> för att fylla ett eget behov jag hade; att validera och generera personnummer att testa applikationer med. Den bygger till viss del på mitt open source paket <a href="https://github.com/olssonm/swedish-entity" target="_blank" rel="noopener"><code>olssonm/swedish-entity</code></a>.</p>
<p>Visar sig att <em>väldigt</em> många fler hade samma behov, då denna lilla enkla sajt är bland mina mest besökta just nu med uppåt 1000 genererade personnummer per dag.</p>
<p>Men, vad många verkar ha missat (trots en liten notis om detta) är att den genererade slumpade personnummer – vilket kan innebära att personnumret faktiskt tillhör verkliga personer.</p>
<p>Som en lösning så finns nu hela Skatteverkets databas över testpersonnummer, personnummer som inte ska finns ute i cirkulation i befolkningen, inladdade och man kan välja dem urval istället för helt slumpmässiga personnummer. Gör det hela mycket mer &quot;säkert&quot; att använda.</p>
<p><em>This article, "personnummer.se v2", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/personnummerse-v2</guid>
                <pubDate>Tue, 28 Oct 2025 07:52:21 +0100</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Nya Laravel Forge är här!]]></title>
                <link>https://marcusolsson.me/artiklar/nya-laravel-forge-ar-har</link>
                <description><![CDATA[<p><a href="/artiklar/laravel-forge-och-homestead">Efter 11 år</a> (!) har <a href="https://forge.laravel.com/" target="_blank" rel="noopener">Laravel Forge</a> fått sig en ordentligt uppgradering – både när det kommer till gränssnitt och funktionalitet.</p>
<p>Samtidigt så har de lanserat &quot;Laravel VPS&quot;, deras egna alternativ till externa VPS-lösningar.</p>
<h2>Forge</h2>
<p>I våras så <a href="/artiklar/laravel-12-och-laravel-cloud">släpptes Laravels egna &quot;Managed Cloud&quot;-lösning</a> &quot;Laravel Cloud&quot; som snabbt har blivit väldigt populärt för dem som inte vill hantera servrar utan endast är ute efter att snabbt publicera sina appar.</p>
<p>Många var då lite oroliga över att Forge kanske skulle falla lite i skymundan.</p>
<p>Visade sig att man inte alls behövde vara orolig. Nu har de anpassat samma designspråk som de använde för Laravel Cloud till Laravel Forge – vilket är en massiv förbättring från det tidigare gränssnittet. Allting är betydligt mer överblickbart och tydligare – även om det efter 11 år på den gamla plattformen tar en stund att hitta rätt. <code>CMD+K</code> finns numera dock för att hjälpa en.</p>
<p><img src="https://cdn.marcusolsson.me/media/2025/10/laravel-forge-2025.jpg" alt="Laravel Forge 2025" /></p>
<p>Bland de nya funktionerna är att äntligen ingår &quot;zero downtime deployments&quot; direkt i Forge, istället för att man behöver gå via Envoyer likt tidigare. Detta kommer att spara otroligt mycket tid, huvudvärk och pengar för framtida sajter (OBS – &quot;ZDD&quot; erbjuds endast nya sajter konfigurerade via Forge, ej bakåtkompatibelt).</p>
<p>Forge är fortsatt extremt prisvärt och effektivt om man jobbar med servrar för flera projekt.</p>
<h2>Laravel VPS</h2>
<p>Laravel erbjuder numera en <a href="https://forge.laravel.com/docs/servers/laravel-vps" target="_blank" rel="noopener">VPS direkt genom dem</a> (läser man det finstilta så ser man dock att detta är genom DigitalOcean).</p>
<p>Kanske inget märkvärdigt med detta egentligen mer än att de erbjuder extrem snabb setup/provision. Runt 10 sekunder tar det att skapa och sätta upp servern. Rimligt prissatt likaså.</p>
<p>I slutändan kanske mest smidigt för dem som inte vill mecka med externa leverantörer som AWS, DigitalOcean eller annan tredjepartslösning och hantera sina kostnader direkt via Forge.</p>
<p>–</p>
<p>Forge har genom åren varit ett av de viktigaste verktygen i mitt arbete – i alla fall det som har sparat mest tid per krona spenderat. Jag är väldigt glad att se att Laravel-teamet fortsätter att satsa på Forge dess användare.</p>
<p><em>Allt nytt kring Forge och Laravel VPS kan du läsa <a href="https://laravel.com/blog/everything-you-need-to-know-about-the-new-forge-laravel-vps" target="_blank" rel="noopener">direkt på Laravels officiella blogg</a>.</em></p>
<p><em>This article, "Nya Laravel Forge är här!", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/nya-laravel-forge-ar-har</guid>
                <pubDate>Sun, 05 Oct 2025 15:02:02 +0200</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Att ta MC-körkort]]></title>
                <link>https://marcusolsson.me/artiklar/att-ta-mc-korkort</link>
                <description><![CDATA[<p>Ett litet annorlunda inlägg här på <a href="https://marcusolsson.me">marcusolsson.me</a> – men tänker ändå att målgruppen kanske träffar någorlunda; IT-konsult på 30+ som har gått och funderat på att äntligen skaffa det där MC-körkortet (eller A-körkort som det egentligen heter).</p>
<p>Hittade själv inte heller så mycket info kring uppkörningar i Borås, så tänkte att det här inlägget kanske är till nytta för någon annan.</p>
<p>I mitt eget fall har jag gått och funderat på A-körkort till och från sedan 20-årsåldern (då A2-körkort), men i år fanns äntligen luckan i schemat och utrymme i budgeten för att faktiskt ta tag i det.</p>
<p>På knappt två månader gick jag från att i princip aldrig ha kört något motordrivet på två hjul till att klara uppkörningen. Började köra i början av augusti och hade uppkörning i slutet av september.</p>
<h2>Moment</h2>
<p>De grundläggande delarna för ett A-körkort är egentligen likadant som att ta B-körkort (d.v.s. för personbil); man behöver skaffa ett lämplighetsintyg, genomföra riskutbildningarna (&quot;1&quot; och &quot;2&quot;) sedan klara teoriprov samt uppkörningen.</p>
<h2>Utbildning och körskola</h2>
<p>Utbildningen för MC kan skilja sig markant ifrån den för personbil dock – de allra flesta som tar A-körkort har redan körkort för personbil, så fokusen ligger i princip helt och hållet på att klara uppkörningen och vad som skiljer mellan en motorcykel och bil. Inte så mycket fokus vid individuella småmoment som med bil.</p>
<p>Uppkörningen för MC är nämligen ganska annorlunda än den för personbil, innan du ens får köra i trafik på behöver du demonstrera flera moment på en manöverbana:</p>
<ul>
<li>Körning i krypfart på lågfartsbana</li>
<li>Undanmanöver på högfartsbana</li>
<li>Kraftig inbromsning till stillastående från 70 och 90km/h</li>
</ul>
<p>Nästan halva utbildningstiden gick åt till att träna de delarna så att de satt så gott som prickfritt.</p>
<p>Känner man någon med MC som kan tänka sig vara handledare så är det värdefullt, särskilt för att få in mer timmar på motorcykeln och få erfarenhet i trafik. Samtidigt så har man sett och hört folk som har blivit lärda  fel (vissa moment, regler och rekommendationer har även ändrats de senaste 10-20 åren) – så ett par lektioner på körskola är att rekommendera starkt i alla fall.</p>
<p>Jag själv hade dessvärre inte alls tillgång till privat handledare, så jag fick köra uteslutande via körskolan vilket såklart kostar lite extra. Men funkade ändå bra – de vet dessutom exakt vad provförättaren är ute efter och hur nuvarande rekommendationer ser ut.</p>
<p>14 lektioner + en extra teknik-/manöverkurs tog jag. En MC-lektion är som regel 80 minuter, så totalt 20h (+2h kurs) på motorcykel innan uppkörning. Om man har tillgång till privat handledare så skulle jag nästan rekommendera att satsa på det dubbla i alla fall för att vara än mer säker i sadeln.</p>
<p>Mina lärare sade efter ~12 lektioner att jag var redo för uppkörning, men jag bokade därefter in någon extra på manöverbanan och stadstrafik för att vara på den säkra sidan då jag ändå hade tiden.</p>
<h2>Teori och uppkörning</h2>
<h3>Teori</h3>
<p>Teoriprovet ska inte vara några större problem om man redan har B-körkort. Jag rekommenderar att man skaffar en teoriapp (själv använde jag &quot;<a href="https://www.ikorkortmc.se/" target="_blank" rel="noopener">iKörkort MC</a>&quot;, mycket bra) och läsa igenom pärm till pärm 2-3 ggr och sedan köra testproven ett dussintal gånger.</p>
<p>Teoriprovet för MC är nästan identiskt som för personbil, där kanske 5-10 frågor är mer MC-specifika (främst kring placering, säkerhet, själva maskinen och klassificeringen av motorcyklar).</p>
<h3>Uppkörning</h3>
<p>Jag körde upp i Borås, där första momenten – manöverbanan – ligger ute vid Viareds flygplats (fr.o.m. 2026 kommer det att vara vid Ryssnäs). Vi var en liten grupp på endast tre personer som samlades på morgonen där körskolan erbjöd lite uppvärmning strax innan vilket är att rekommendera så att man inte kommer in helt &quot;kall&quot;.</p>
<p>Därefter anlände provförättaren från Trafikverket som gick igenom de olika momenten och hur dagen skulle se ut. Han var tydlig med att han inte släppte ut någon i trafiken som inte klarade manöverbanan, vid små fel så skulle man bli erbjuden max ett extra försök per moment. Han sade även att fuskande med hastighet (t.ex. att köra 45 istället för 50km/h på högfartsbanan skulle resultera i ett nytt försök).</p>
<p>Jag var sist ut i gruppen. Trots nerver lyckades jag klara samtliga delar utan några direkta konstigheter. Var kanske lite wobblig på lågfartsbanan då jag överdrev hastigheten och endast höll ca. 4km/h som jag lyckades rädda upp med kopplingen.</p>
<p>Samtliga i gruppen blev klara för trafik efter manöverbanan vilket var kul att se.</p>
<p>Då jag hade kört sist och redan satt på motorcykeln så fick jag köra först i trafik och utgick därmed ifrån Viared, i annat fall är det ifrån Trafikverkets nya lokaler i Druvefors som gäller.</p>
<p>För de som känner till Borås; jag fick köra igenom industriområdet Viared, landsväg (Funningevägen ut mot Bosnäs och tillbaka), på och avfarter på Rv27 (Trafikplats Osdal), tätortskörning främst på Göta (via Varbergsvägen), lite filbyten och &quot;destinationsplanering&quot; vid Brodalsmotet (Gina Tricot-huset/Makrillen) och därefter tillbaka till Trafikverket på Druvefors. Totalt strax över 30 minuter.</p>
<p>Ett tag på Göta körde vi högersvängar runt Bredalsgatan-Götagatan-Alvestagatan 2-3ggr vilket jag tyckte var lite skumt, men förstod att jag förmodligen hade gjort något misstag som han ville dubbelkolla – så jag var extra noggrann med döda vinkeln över cykelbanan, inbromsning (fram + bakbroms), placeringen och bromsberedskap vid utfarterna. Efter avslutat uppkörning bekräftade han att han tyckte jag hade slarvat med högerplacering vid korsning i första varvet – och därför hade vi kört dem ett par gånger till där han såg att jag rättade till det.</p>
<p>Annat så tyckte han att det såg väldigt bra ut och meddelade att han markerar körprovet som godkänt. Fem minuter senare fick jag resultatet via mail.</p>
<h4>Uppkörningstips</h4>
<p>Inga direkta nya moment ska dyka upp på uppkörningen om man har tränat/tränats ordentligt. Utan var fokuserad, var lugn och se det som en vanlig körlektion där du ska visa upp allt du har lärt dig.</p>
<ul>
<li>Bromsberedskap! Dolda utfarter är en potentiell livsfara, visa att du är beredd. Likadant i korsningar med högerregel, lys här gärna upp bromshjuset (utan kraftfull inbromsning såklart) för att påminna bakomliggande bilar.</li>
<li>Använd alltid både fram- och bakbroms.</li>
<li>Landsväg; håll långt till höger i dolda kurvor. Något till höger i backkrön. Vid fri sikt, skär linjer något.</li>
<li>I trafik, placering; vid korsning <em>utan</em> färdriktningsmarkeringar håll långt till höger/vänster vid höger- och vänstersväng. (Här går ju åsikterna isär något, men är vad de lär ut och vill se i Borås i alla fall.) I annat fall är körfältet ditt – gör dig &quot;stor&quot;.</li>
<li>Glöm inte att stänga av blinkers!</li>
<li>Det vanliga; överdriv backspegelkontroll, check av döda vinkeln o.s.v.</li>
</ul>
<p>Provförättaren var också väldigt tydlig med att han inte ville se någon &quot;mesåkning&quot;, utan att han behöver se hur man kör &quot;på riktigt&quot;. Ordentliga accelerationer vid fri sikt och väg. Man ska köra defensivt, men för låga hastigheter och överdriven försiktighet ser inte bra ut och ger ett osäkert intryck vilket kan vara orsak för kuggning.</p>
<p>Till sist, var ödmjuk och känn till dina egna begränsningar. Läser man forum och annat om uppkörningen får man lätt intrycket att världens bästa MC-förare blir kuggade till höger och vänster. Det sker förmodligen extremt sällan. Blir man kuggad så har man förmodligen gjort ett allvarligt fel eller har tillräckligt många småbrister att man helt enkelt inte är en säker förare, antingen för sig själv eller andra. Ta en extra lektion och be läraren vara kritisk så att du får chansen att rätta till eventuella brister.</p>
<p>Trafikverket (tillsammans med STR) har en väldigt <a rel="nofollow noopener" href="https://www.trafikverket.se/bli-en-tankande-och-saker-mc-forare/" target="_blank">bra sida kring vad provförättaren tittar på och hur man kan identifiera sina egna brister</a>.</p>
<h2>Kostnad</h2>
<p>Att ta MC-kort är dyrt, så enkelt är det. Om man kör även privat så kommer man såklart ner i pris för lektionerna, men man behöver ändå vara beredd på att betala en hel del. I mitt fall delade jag upp kostnaderna i tre kategorier; obligatoriska delar, körlektioner och &quot;övrigt&quot;.</p>
<h3>Obligatoriska delar</h3>
<p>Dessa kommer man inte undan; utan detta är för Trafikverkets avgifter samt de obligatoriska riskutbildningarna (där priset kan variera kraftigt mellan de olika körskolorna).</p>
<table>
    <tr>
        <td><strong>Moment</strong></td>
        <td><strong>Kostnad</strong></td>
    </tr>
    <tr>
        <td>
            Synundersökning
        </td>
        <td>
            400kr
        </td>
    </tr>
    <tr>
        <td>
            Risk 1
        </td>
        <td>
            900kr
        </td>
    </tr>
    <tr>
        <td>
            Risk 2
        </td>
        <td>
            3 200kr
        </td>
    </tr>
    <tr>
        <td>
            Fotografering (Tfv)
        </td>
        <td>
            120kr
        </td>
    </tr>
    <tr>
        <td>
            Teoriprov (Tfv)
        </td>
        <td>
            420kr
        </td>
    </tr>
    <tr>
        <td>
            Körprov (Tfv)
        </td>
        <td>
            2 000kr
        </td>
    </tr>
    <tr>
        <td>
            Tillverkning körkort (Tfv)
        </td>
        <td>
            375kr
        </td>
    </tr>
    <tr>
        <td>
            <strong>Totalt</strong>
        </td>
        <td>
            <strong>7 415kr</strong>
        </td>
    </tr>
</table>
<p>Så kör du helt privat, behöver inte hyra motorcykel eller köpa utrustning och klarar körprovet på första försöket så kan du i bästa fall komma undan med blott 7 415kr.</p>
<h3>Körlektioner</h3>
<p>Antalet körlektioner varierar såklart kraftigt från person till person; finns de som bara tar någon eller några. Men jag träffade en på riskutbildningen som hade närmare 30 lektioner genomförda och/eller bokade. I mitt fall:</p>
<table>
    <tr>
        <td><strong>Moment</strong></td>
        <td><strong>Kostnad</strong></td>
    </tr>
    <tr>
        <td>
            Körlektion 14st á 1480kr
        </td>
        <td>
            20 720kr
        </td>
    </tr>
    <tr>
        <td>
            Manöverkurs (Vårgårda)
        </td>
        <td>
            1 800kr
        </td>
    </tr>
    <tr>
        <td>
            <strong>Totalt</strong>
        </td>
        <td>
            <strong>22 520kr</strong>
        </td>
    </tr>
</table>
<h3>Övrigt</h3>
<p>Denna kategori kanske inte tillämpas för alla beroende på vilka förutsättningar man har. Kör man t.ex. via körskola så finns nästan all utrustning att låna, men rekommenderar ändå att köpa den själv om man har möjlighet – dels så känns det bättre när allt sitter &quot;rätt&quot; och man slipper använda en hjälm som har används av 3-4 andra personer den dagen i 30 graders värme... Blir lättare att fokusera på rätt saker helt enkelt.</p>
<table>
    <tr>
        <td><strong>Moment</strong></td>
        <td><strong>Kostnad</strong></td>
    </tr>
    <tr>
        <td>
            MC-utrustning
        </td>
        <td>
            12 900kr
        </td>
    </tr>
    <tr>
        <td>
            Teorimaterial (appar + bok)
        </td>
        <td>
            1 000kr
        </td>
    </tr>
    <tr>
        <td>
            Hyra av MC vid uppkörning
        </td>
        <td>
            1 800kr
        </td>
    </tr>
    <tr>
        <td>
            <strong>Totalt</strong>
        </td>
        <td>
            <strong>15 700kr</strong>
        </td>
    </tr>
</table>
<p>Man kan realistiskt förmodligen komma undan med ~7-8000kr för utrustningen. Men man vill ändå ha något som man kan köra med i både varmt och svalare väder – och att den har rätt skyddsklassning såklart. Är man ändå inställd på att ta kortet så köp också en kvalitétshjälm direkt – sitter bättre, är tystare och har ofta bättre alternativ för framtida uppgraderingar (visir, intercom o.s.v.).</p>
<p>Totalt pris för mitt körkort inkl. skyddsutrustning blev alltså 45 635kr. Vilket såklart är en hutlös summa för de flesta. Lägg därtill eventuell förlorad lön för kurser och prov o.s.v. så är det fullt förståeligt varför A-körkort är och förblir en dröm för många.</p>
<p>Värt att tillägga dock är att man knappst behöver göra det i så snabbt tempo; många kör någon lektion och gör Risk 1 på hösten, och sedan tar resten på våren.</p>
<h1>Summering</h1>
<p>Är det värt det då? Det kan endast en själv svara på!</p>
<p>I mitt fall så har det verkligen varit det; äntligen så behöver jag inte fundera mer på detta efter alla år. En ny färdighet att checka av.</p>
<p>Man har också fått träffa nya intressanta människor och man har fått sig en tankeställare kring olika delar av trafiken som förmodligen även har gjort en till en bättre och säkrare bilförare. Inte minst så har det varit roligt (om än lite stressigt och nervöst emellanåt)!</p>
<p>Ett sista tips om detta är något du verkligen är intresserad av; boka i tid! Väldigt ont om utbildnings- och uppkörningstider. Bokade i mars/april och de hade de precis en enda ledig uppkörningstid bland säsongens sista veckor i september med start för övningskörning i augusti.</p>
<p>Nu blir det till att budgetera för inköp av en egen motorcykel inför kommande säsong – förmodligen någon av de populära mellanklassarna som första modell (står mellan CB750, MT-07/XSR 700 eller kanske en GSX-8?)</p>
<p><strong>Ses på vägarna – kör säkert!</strong></p>
<p><em>This article, "Att ta MC-körkort", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/att-ta-mc-korkort</guid>
                <pubDate>Tue, 23 Sep 2025 20:30:11 +0200</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Google: vi förstör inte sökresultaten]]></title>
                <link>https://marcusolsson.me/artiklar/google-vi-forstor-inte-sokresultaten</link>
                <description><![CDATA[<p>Som bekant så presenterar <a href="/artiklar/kategorier/google">Google</a> numera värdelösa AI-svar på en sökning, som ofta är direkt felaktiga och med tvivelaktiga källor. Detta efter att i ett halvt decennium redan ha försämrat sökresultaten genom att belöna SEO-stuffing, annonser och irrelevanta sajter i sökresultaten.</p>
<p>Efter flera undersökningar och analyser den senaste tiden<sup id="fnref:1"><a href="#fn:1" role="doc-noteref">1</a></sup> som pekar på att AI-svaren ger en sämre CTR (click through rate) till faktiskt relevanta webbplatser slår Google nu ifrån sig<sup id="fnref:2"><a href="#fn:2" role="doc-noteref">2</a></sup> – och istället hävdar att AI istället faktiskt leder till mer trafik och &quot;higher quality clicks&quot;.</p>
<p>Google kanske menar att det leder till fler klick, bara inte genom Google utan genom alternativ så som <a href="https://duckduckgo.com/" target="_blank" rel="noopener">DuckDuckGo</a>?</p>
<p>–</p>
<p>Anekdotisk bevis, ja visst, men mina egna sajter har sett en stagnering av trafik från Google (och i vissa fall ett tapp) över en 24-månaders period. Medan trafik från t.ex. DuckDuckGo och Bing har gått upp flera 100% (förvisso från väldigt små volymer för två år sedan). Men, utav någon anledning får en av mina andra bloggar (<a href="https://olssonbygger.se" target="_blank" rel="noopener">olssonbygger.se</a>) väldigt mycket trafik från ChatGPT, många som bygger altaner med hjälp av en chatbot?</p>
<p>Googles index är fortfarande bäst i mitt tycke när det kommer till nischade ämnen och om man orkar scrolla förbi annonser, AI-svar och Reddit-inlägg. Men annars så är DuckDuckGo en betydligt bättre användarupplevelse som fortfarande visar det man vill ha; relevanta sökresultat – dessutom utan att sälja all ens information. Bytte för över ett år sedan och kan räkna på en hand hur många gånger i månaden jag använder Google.</p>
<div role="doc-endnotes"><hr /><ol><li id="fn:1" role="doc-endnote"><p>Ars Technica: <a href="https://arstechnica.com/ai/2025/07/research-shows-google-ai-overviews-reduce-website-clicks-by-almost-half/" target="_blank" rel="noopener">Surprising no one, new research says AI Overviews cause massive drop in search clicks</a>&nbsp;<a rev="footnote" href="#fnref:1" role="doc-backlink">↩</a></p></li>
<li id="fn:2" role="doc-endnote"><p>Google Blog: <a href="https://blog.google/products/search/ai-search-driving-more-queries-higher-quality-clicks/" target="_blank" rel="noopener">AI in Search is driving more queries and higher quality clicks</a>&nbsp;<a rev="footnote" href="#fnref:2" role="doc-backlink">↩</a></p></li></ol></div>
<p><em>This article, "Google: vi förstör inte sökresultaten", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/google-vi-forstor-inte-sokresultaten</guid>
                <pubDate>Thu, 07 Aug 2025 13:29:09 +0200</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Min webbplats har blivit stulen]]></title>
                <link>https://marcusolsson.me/artiklar/min-webbplats-har-blivit-stulen</link>
                <description><![CDATA[<p>Under alla år som jag har jobbat som frilansande webbutvecklare och skrivit för webben i 15+ år har man råkat ut för plagiering både en och två gånger. Jag har råkat ut för både webbyråer som har stulit artiklar, konkurrerande frilansare som har kopierat företagsbeskrivning (och försökt kopiera företagsnamn!) Men för några dagar sedan fick jag tips om det värsta hittills.</p>
<p>En konkurrerande webbutvecklare som har stulit all design och text från min webbplats. Visst att &quot;Imitation is the sincerest form of flattery&quot; och allt det där, men att titulera sig själv som webbutvecklare/-designer och sedan själva något som någon annan har lagt tid och energi på att skapa är mest pinsamt och ganska sorgligt.</p>
<p><strong>Startsida</strong></p>
<p><img src="https://cdn.marcusolsson.me/media/2025/05/1-orginal.png" alt="Startsida original" />
<img src="https://cdn.marcusolsson.me/media/2025/05/1-plagiat.jpg" alt="Startsida plagiat" /></p>
<p><strong>Tjänsteutbud</strong></p>
<p><img src="https://cdn.marcusolsson.me/media/2025/05/2-orginal.png" alt="Tjänsteutbud original" />
<img src="https://cdn.marcusolsson.me/media/2025/05/2-plagiat.png" alt="Tjänsteutbud plagiat" /></p>
<p><strong>Kontaktsida</strong></p>
<p><img src="https://cdn.marcusolsson.me/media/2025/05/3-orginal.png" alt="Kontaktsida original" />
<img src="https://cdn.marcusolsson.me/media/2025/05/3-plagiat.png" alt="Kontaktsida plagiat" /></p>
<p>T.o.m. idén till favicon:en är kopierad...!?</p>
<p><img src="https://cdn.marcusolsson.me/media/2025/05/favicon.jpg" alt="Plagierad favicon" /></p>
<p>Får väl ge lite cred till att den som har kopierat har uppdaterat designen något (har själv inte uppdaterat på snart 3+ år). Men det som är mest störande är ändå texten, då detta är min personliga text som jag har skrivit och uppdaterat år efter år, tycker att det är ganska oförsvarbart att stjäla den rakt av.</p>
<p>Men vad ska man göra då? I teorin kan jag ju stämma i domstol då all originel text är upphovsrättsskyddad i Sverige. Men så långt ska det förhoppningsvis inte gå, istället prövade jag att höra av mig till förövaren och hoppas på att han väljer att plocka ner det och skriver ihop något eget istället. Får se om han väljer att lyssna.</p>
<p>Väldigt tråkigt är det i alla fall. Uppdatering kommer när något nytt sker.</p>
<p><strong>Uppdaterat:</strong> Den andra parten har plockat ner webbplatsen och bett om ursäkt – så detta är överspelat.</p>
<p><em>This article, "Min webbplats har blivit stulen", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/min-webbplats-har-blivit-stulen</guid>
                <pubDate>Mon, 05 May 2025 22:13:00 +0200</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 12 (och Laravel Cloud)]]></title>
                <link>https://marcusolsson.me/artiklar/laravel-12-och-laravel-cloud</link>
                <description><![CDATA[<p>Nytt år – ny version av Laravel! Denna gång handlar uppdateringen mer om ekosystemet än själva ramverket – med Laravel Cloud, en uppdaterad sajt och nya starter kits.</p>
<p>Vad som också är lite speciellt för i år är att det i princip inte finns några &quot;breaking changes&quot; mellan Laravel 11 och 12<sup id="fnref:1"><a href="#fn:1" role="doc-noteref">1</a></sup>. Kör ens projekt Laravel 11 så ska det gå att uppdatera till Laravel 12 rakt av.</p>
<p>Vad större fokus har varit i år är ekosystemet för Laravel i stort. Nytt är Laravel Cloud, och Laravel (som produkt) har fått en uppdaterad grafisk profil.</p>
<h2>Ny grafisk profil och sajt</h2>
<p><a href="https://laravel.com" target="_blank" rel="noopener">laravel.com</a> har fått sig ett nytt lager av färg och förbättrad struktur. Dokumentationen är lika lätt att hitta till och söka igenom som tidigare, men de har förtydligat ekosystemet där de pekar ut vad som är en &quot;produkt&quot; (som kostar pengar) och vad som ingår i deras paraply of officiella open source paket (som t.ex. Socialite och Horizon – men inte Livewire...?).</p>
<p><img src="https://cdn.marcusolsson.me/media/2025/02/laravel-new-website.png" alt="Laravel featured products" /></p>
<p>Vid intresse så gick Laravels nya &quot;Head of design&quot; David Hill igenom designtänket vid Laracon EU häromveckan, väl värt att ta en titt.</p>
<iframe height="315" src="https://www.youtube-nocookie.com/embed/WrKo1kn1Wkk?si=uFNSkiw5z7aoPOGD" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h2>Starter kits</h2>
<p>Nytt är också att de har gjort om konceptet kring &quot;<a href="https://laravel.com/docs/12.x/starter-kits#main-content">starter kits</a>&quot;. Alltså valfria tillägg som du kan lägga till vid en ny installation för att få autentisering o.s.v. &quot;gratis&quot;. Jag själv har alltid använt mina egna mellan projekt, och har tyckt att skillnaderna mellan tidigare &quot;Jetstream&quot; och &quot;Breeze&quot; var väldigt knepiga.</p>
<p>Nu väljer man istället sin stack; React, Vue eller Livewire. De två förstnämnda kommer med Tailwind/<a href="https://ui.shadcn.com/" target="_blank" rel="noopener">shadcn</a>, och Livewire kommer med sitt egna &quot;<a href="https://fluxui.dev/" target="_blank" rel="noopener">Flux</a>&quot;.</p>
<p>Ska bli spännande att pröva Livewire-kitet vid kommande projekt.</p>
<h2>Laravel Cloud</h2>
<p>Laravel har nu lanserat sin egna &quot;Managed Cloud&quot;-lösning som de kort och gott kallar för &quot;Cloud&quot;.</p>
<p>Cloud strömlinjeformar ens setup där man helt enkelt väljer vilken kod som ska deployas, kopplar ihop en databas (och cache + fillagring ) och klickar på deploy. Cloud tar hand om resten. Allt ifrån autoscaling till SSL-cert etc.</p>
<p>Testat runt lite och måste säga att gränssnittet är superbt – detta har de lyckats väldigt bra med. Men det är nog sällan en tjänst som jag skulle ha användning av då jag föredrar att ha full kontroll över mina servrar, så jag stannar på Forge i en överskådlig framtid.</p>
<p><img src="https://cdn.marcusolsson.me/media/2025/02/laravel-cloud.png" alt="Laravel Cloud" /></p>
<p>Det skulle då eventuellt vara för enklare kundlösningar där man inte behöver installera egna paket på servern som detta skulle kunna bli aktuellt.</p>
<p>Som alltid med denna typen av produkter så är priset alltid ett frågetecken också, blir alltid i förväg svårt att budgetera. Komplett prislista för compute, db o.s.v. <a href="https://cloud.laravel.com/docs/pricing#compute" target="_blank" rel="noopener">finns här</a>. Klart är i alla fall att om jag skulle flytta mina 100+ sajter och projekt ifrån Forge till Cloud så skulle det kosta en mindre förmögenhet.</p>
<p>Blir också lite fundersam var tidigare &quot;<a href="https://vapor.laravel.com/" target="_blank" rel="noopener">Vapor</a>&quot; passar in i detta. Det är snarlikt Cloud, men är låst endast till AWS Lambda. Cloud stödjer &quot;hibernation&quot;, så tror inte Vapor kommer vara särskilt relevant framöver.</p>
<div role="doc-endnotes"><hr /><ol><li id="fn:1" role="doc-endnote"><p>Som alltid finns specialfall. Spana alltid igenom deras alltid lika förträffliga <a href="https://laravel.com/docs/12.x/upgrade" target="_blank" rel="noopener">Upgrade Guide</a>&nbsp;<a rev="footnote" href="#fnref:1" role="doc-backlink">↩</a></p></li></ol></div>
<p><em>This article, "Laravel 12 (och Laravel Cloud)", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/laravel-12-och-laravel-cloud</guid>
                <pubDate>Tue, 25 Feb 2025 10:03:26 +0100</pubDate>
                            </item>
                    <item>
                <title><![CDATA[App för att kryptera meddelanden]]></title>
                <link>https://marcusolsson.me/artiklar/app-for-att-kryptera-meddelanden</link>
                <description><![CDATA[<p>Flera gånger de senaste månaderna har jag tagit emot leveranser av t.ex. lösenord och API-nycklar, och det blir alltid lite krångel med hur man ska leverera dem. Man vill ju gärna inte skicka dem direkt i ett mail.</p>
<p>Dela via 1Password? Helt okej. Krypterad .zip med separat leverans av lösenord via SMS? Funkar för det mesta. &quot;Okända&quot; externa tjänster börja bli lite mer känsligt … och att be folk att signa upp för t.ex. <a href="https://keybase.io/" target="_blank" rel="noopener">Keybase</a> kan vara mycket begärt (men ändå enklare än att be någon köra PGP lokalt).</p>
<p>Så jag snickrade ihop en <a href="/kryptera">enkel webbapp</a> med <a href="https://alpinejs.dev/" target="_blank" rel="noopener">Alpine.js</a> och <a href="https://openpgpjs.org/" target="_blank" rel="noopener">OpenPGP.js</a> som läser in min publika PGP-nyckel och tillåter en att kryptera meddelanden ämnade för mig. Därefter kan jag dekryptera meddelandet enkelt med min privata nyckel.</p>
<p>Själva appen blev på knappt 30 rader:</p>
<pre><code data-theme="dark" data-lang="javascript" style='background-color: #24292e; --theme-selection-background: #39414a;'><!-- Syntax highlighted by torchlight.dev --><div><span> 1</span><span>document.</span><span>addEventListener</span><span>(</span><span>&#39;alpine:init&#39;</span><span>, () </span><span>=&gt;</span><span> {</span></div><div><span> 2</span><span>    Alpine.</span><span>data</span><span>(</span><span>&#39;encryptor&#39;</span><span>, () </span><span>=&gt;</span><span> ({</span></div><div><span> 3</span><span>        message: </span><span>&#39;&#39;</span><span>,</span></div><div><span> 4</span><span>        encryptedMessage: </span><span>&#39;&#39;</span><span>,</span></div><div><span> 5</span>&nbsp;</div><div><span> 6</span><span>        </span><span>async</span><span> </span><span>fetchPGPKey</span><span>(</span><span>url</span><span>) {</span></div><div><span> 7</span><span>            </span><span>const</span><span> </span><span>response</span><span> </span><span>=</span><span> </span><span>await</span><span> </span><span>fetch</span><span>(url);</span></div><div><span> 8</span><span>            </span><span>return</span><span> response.</span><span>text</span><span>();</span></div><div><span> 9</span><span>        },</span></div><div><span>10</span><span>        </span><span>async</span><span> </span><span>encryptMessage</span><span>(</span><span>publicKeyArmored</span><span>, </span><span>message</span><span>) {</span></div><div><span>11</span><span>            </span><span>const</span><span> </span><span>publicKey</span><span> </span><span>=</span><span> </span><span>await</span><span> openpgp.</span><span>readKey</span><span>({ armoredKey: publicKeyArmored });</span></div><div><span>12</span><span>            </span><span>const</span><span> </span><span>encryptedMessage</span><span> </span><span>=</span><span> </span><span>await</span><span> openpgp.</span><span>encrypt</span><span>({</span></div><div><span>13</span><span>                message: </span><span>await</span><span> openpgp.</span><span>createMessage</span><span>({ text: message }),</span></div><div><span>14</span><span>                encryptionKeys: publicKey,</span></div><div><span>15</span><span>            });</span></div><div><span>16</span>&nbsp;</div><div><span>17</span><span>            </span><span>return</span><span> encryptedMessage;</span></div><div><span>18</span><span>        },</span></div><div><span>19</span><span>        </span><span>async</span><span> </span><span>encrypt</span><span>() {</span></div><div><span>20</span><span>            </span><span>const</span><span> </span><span>publicKeyURL</span><span> </span><span>=</span><span> </span><span>&#39;-----BEGIN PGP PUBLIC KEY BLOCK-----xxx&#39;</span><span>;</span></div><div><span>21</span><span>            </span><span>try</span><span> {</span></div><div><span>22</span><span>                </span><span>const</span><span> </span><span>publicKeyArmored</span><span> </span><span>=</span><span> </span><span>await</span><span> </span><span>this</span><span>.</span><span>fetchPGPKey</span><span>(publicKeyURL);</span></div><div><span>23</span><span>                </span><span>this</span><span>.encryptedMessage </span><span>=</span><span> </span><span>await</span><span> </span><span>this</span><span>.</span><span>encryptMessage</span><span>(publicKeyArmored, </span><span>this</span><span>.message);</span></div><div><span>24</span><span>            } </span><span>catch</span><span> (error) {</span></div><div><span>25</span><span>                console.</span><span>error</span><span>(</span><span>&#39;Encryption failed:&#39;</span><span>, error);</span></div><div><span>26</span><span>                </span><span>this</span><span>.encryptedMessage </span><span>=</span><span> </span><span>&#39;Encryption error.&#39;</span><span>;</span></div><div><span>27</span><span>            }</span></div><div><span>28</span><span>        }</span></div><div><span>29</span><span>    }));</span></div><div><span>30</span><span>});</span></div></code><code data-theme="light" data-lang="javascript" style='background-color: #fff; --theme-selection-background: #e2e5e9;'><!-- Syntax highlighted by torchlight.dev --><div><span> 1</span><span>document.</span><span>addEventListener</span><span>(</span><span>&#39;alpine:init&#39;</span><span>, () </span><span>=&gt;</span><span> {</span></div><div><span> 2</span><span>    Alpine.</span><span>data</span><span>(</span><span>&#39;encryptor&#39;</span><span>, () </span><span>=&gt;</span><span> ({</span></div><div><span> 3</span><span>        message: </span><span>&#39;&#39;</span><span>,</span></div><div><span> 4</span><span>        encryptedMessage: </span><span>&#39;&#39;</span><span>,</span></div><div><span> 5</span>&nbsp;</div><div><span> 6</span><span>        </span><span>async</span><span> </span><span>fetchPGPKey</span><span>(</span><span>url</span><span>) {</span></div><div><span> 7</span><span>            </span><span>const</span><span> </span><span>response</span><span> </span><span>=</span><span> </span><span>await</span><span> </span><span>fetch</span><span>(url);</span></div><div><span> 8</span><span>            </span><span>return</span><span> response.</span><span>text</span><span>();</span></div><div><span> 9</span><span>        },</span></div><div><span>10</span><span>        </span><span>async</span><span> </span><span>encryptMessage</span><span>(</span><span>publicKeyArmored</span><span>, </span><span>message</span><span>) {</span></div><div><span>11</span><span>            </span><span>const</span><span> </span><span>publicKey</span><span> </span><span>=</span><span> </span><span>await</span><span> openpgp.</span><span>readKey</span><span>({ armoredKey: publicKeyArmored });</span></div><div><span>12</span><span>            </span><span>const</span><span> </span><span>encryptedMessage</span><span> </span><span>=</span><span> </span><span>await</span><span> openpgp.</span><span>encrypt</span><span>({</span></div><div><span>13</span><span>                message: </span><span>await</span><span> openpgp.</span><span>createMessage</span><span>({ text: message }),</span></div><div><span>14</span><span>                encryptionKeys: publicKey,</span></div><div><span>15</span><span>            });</span></div><div><span>16</span>&nbsp;</div><div><span>17</span><span>            </span><span>return</span><span> encryptedMessage;</span></div><div><span>18</span><span>        },</span></div><div><span>19</span><span>        </span><span>async</span><span> </span><span>encrypt</span><span>() {</span></div><div><span>20</span><span>            </span><span>const</span><span> </span><span>publicKeyURL</span><span> </span><span>=</span><span> </span><span>&#39;-----BEGIN PGP PUBLIC KEY BLOCK-----xxx&#39;</span><span>;</span></div><div><span>21</span><span>            </span><span>try</span><span> {</span></div><div><span>22</span><span>                </span><span>const</span><span> </span><span>publicKeyArmored</span><span> </span><span>=</span><span> </span><span>await</span><span> </span><span>this</span><span>.</span><span>fetchPGPKey</span><span>(publicKeyURL);</span></div><div><span>23</span><span>                </span><span>this</span><span>.encryptedMessage </span><span>=</span><span> </span><span>await</span><span> </span><span>this</span><span>.</span><span>encryptMessage</span><span>(publicKeyArmored, </span><span>this</span><span>.message);</span></div><div><span>24</span><span>            } </span><span>catch</span><span> (error) {</span></div><div><span>25</span><span>                console.</span><span>error</span><span>(</span><span>&#39;Encryption failed:&#39;</span><span>, error);</span></div><div><span>26</span><span>                </span><span>this</span><span>.encryptedMessage </span><span>=</span><span> </span><span>&#39;Encryption error.&#39;</span><span>;</span></div><div><span>27</span><span>            }</span></div><div><span>28</span><span>        }</span></div><div><span>29</span><span>    }));</span></div><div><span>30</span><span>});</span></div></code></pre>
<p>Och därtill lite HTML:</p>
<pre><code data-theme="dark" data-lang="html" style='background-color: #24292e; --theme-selection-background: #39414a;'><!-- Syntax highlighted by torchlight.dev --><div><span> 1</span><span>&lt;</span><span>div</span></div><div><span> 2</span><span>    </span><span>x-data</span><span>=</span><span>&quot;{...encryptor()}&quot;</span></div><div><span> 3</span><span>&gt;</span></div><div><span> 4</span><span>    &lt;</span><span>div</span><span> </span><span>x-show</span><span>=</span><span>&quot;!encryptedMessage&quot;</span><span>&gt;</span></div><div><span> 5</span><span>        &lt;</span><span>textarea</span><span> </span><span>x-model</span><span>=</span><span>&quot;message&quot;</span><span>&gt;&lt;/</span><span>textarea</span><span>&gt;</span></div><div><span> 6</span><span>        &lt;</span><span>button</span><span> </span><span>@click</span><span>=</span><span>&quot;encrypt&quot;</span><span>&gt;Kryptera&lt;/</span><span>button</span><span>&gt;</span></div><div><span> 7</span><span>    &lt;/</span><span>div</span><span>&gt;</span></div><div><span> 8</span><span>    &lt;</span><span>div</span><span> </span><span>x-show</span><span>=</span><span>&quot;encryptedMessage&quot;</span><span>&gt;</span></div><div><span> 9</span><span>        &lt;</span><span>textarea</span><span> </span><span>x-model</span><span>=</span><span>&quot;encryptedMessage&quot;</span><span> </span><span>disabled</span><span>&gt;&lt;/</span><span>textarea</span><span>&gt;</span></div><div><span>10</span><span>    &lt;/</span><span>div</span><span>&gt;</span></div><div><span>11</span><span>&lt;/</span><span>div</span><span>&gt;</span></div></code><code data-theme="light" data-lang="html" style='background-color: #fff; --theme-selection-background: #e2e5e9;'><!-- Syntax highlighted by torchlight.dev --><div><span> 1</span><span>&lt;</span><span>div</span></div><div><span> 2</span><span>    </span><span>x-data</span><span>=</span><span>&quot;{...encryptor()}&quot;</span></div><div><span> 3</span><span>&gt;</span></div><div><span> 4</span><span>    &lt;</span><span>div</span><span> </span><span>x-show</span><span>=</span><span>&quot;!encryptedMessage&quot;</span><span>&gt;</span></div><div><span> 5</span><span>        &lt;</span><span>textarea</span><span> </span><span>x-model</span><span>=</span><span>&quot;message&quot;</span><span>&gt;&lt;/</span><span>textarea</span><span>&gt;</span></div><div><span> 6</span><span>        &lt;</span><span>button</span><span> </span><span>@click</span><span>=</span><span>&quot;encrypt&quot;</span><span>&gt;Kryptera&lt;/</span><span>button</span><span>&gt;</span></div><div><span> 7</span><span>    &lt;/</span><span>div</span><span>&gt;</span></div><div><span> 8</span><span>    &lt;</span><span>div</span><span> </span><span>x-show</span><span>=</span><span>&quot;encryptedMessage&quot;</span><span>&gt;</span></div><div><span> 9</span><span>        &lt;</span><span>textarea</span><span> </span><span>x-model</span><span>=</span><span>&quot;encryptedMessage&quot;</span><span> </span><span>disabled</span><span>&gt;&lt;/</span><span>textarea</span><span>&gt;</span></div><div><span>10</span><span>    &lt;/</span><span>div</span><span>&gt;</span></div><div><span>11</span><span>&lt;/</span><span>div</span><span>&gt;</span></div></code></pre>
<p>Funkar riktigt bra för mina ganska enkla behov. Själva <a href="/kryptera">appen hittar du här</a>.</p>
<p><em>This article, "App för att kryptera meddelanden", was first posted on <a href="https://marcusolsson.me">marcusolsson.me.</a></em></p>]]></description>
                <author><![CDATA[Marcus Olsson]]></author>
                <guid>https://marcusolsson.me/artiklar/app-for-att-kryptera-meddelanden</guid>
                <pubDate>Sun, 02 Feb 2025 09:15:50 +0100</pubDate>
                            </item>
            </channel>
</rss>
