<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Edoardo Dusi</title>
    <description>The latest articles on DEV Community by Edoardo Dusi (@edodusi).</description>
    <link>https://dev.to/edodusi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F450%2F8b5686dc-231a-4e76-8e14-ab9bbea6f246.png</url>
      <title>DEV Community: Edoardo Dusi</title>
      <link>https://dev.to/edodusi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/edodusi"/>
    <language>en</language>
    <item>
      <title>Announcing Storyblok Svelte SDK v5: now fully compatible with Svelte 5</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Mon, 28 Apr 2025 09:34:22 +0000</pubDate>
      <link>https://dev.to/storyblok/announcing-storyblok-svelte-sdk-v5-now-fully-compatible-with-svelte-5-3j3i</link>
      <guid>https://dev.to/storyblok/announcing-storyblok-svelte-sdk-v5-now-fully-compatible-with-svelte-5-3j3i</guid>
      <description>&lt;p&gt;We're thrilled to announce the release of &lt;a href="https://github.com/storyblok/storyblok-svelte" rel="noopener noreferrer"&gt;storyblok-svelte v5&lt;/a&gt;, a complete refactoring of our dedicated SDK built specifically for Svelte 5 and its &lt;a href="https://svelte.dev/blog/runes" rel="noopener noreferrer"&gt;runes system&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This new version takes full advantage of Svelte's latest innovations to provide you with the most powerful, developer-friendly tools to integrate your Storyblok content into your Svelte applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embracing the future with Svelte 5
&lt;/h2&gt;

&lt;p&gt;Svelte always stood out for its compiler-focused approach that delivers exceptional performance with minimal runtime overhead.&lt;/p&gt;

&lt;p&gt;With the introduction of &lt;strong&gt;runes&lt;/strong&gt;, the framework took another leap forward into simplicity and power.&lt;/p&gt;

&lt;p&gt;As passionate supporters of the Svelte ecosystem, we've &lt;a href="https://github.com/storyblok/storyblok-svelte/pull/1127" rel="noopener noreferrer"&gt;completely rebuilt our SDK&lt;/a&gt; to embrace these innovations, ensuring that Storyblok users can take full advantage of these new features, while maintaining compatibility with previous versions.&lt;/p&gt;

&lt;p&gt;Let's see what's changed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaner component integration
&lt;/h2&gt;

&lt;p&gt;Working with Storyblok components in Svelte 5 is now more elegant than ever:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Before (Svelte 4) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- After (Svelte 5) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$props&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simplified syntax makes your components more concise while fully leveraging Svelte 5's reactive system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhanced Rich Text rendering
&lt;/h2&gt;

&lt;p&gt;Our rich text renderer is now fully compatible with Svelte 5's reactivity system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderRichText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$props&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Automatically updates when content changes&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;richTextContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;renderRichText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blok&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rich text content now updates seamlessly when edited in the Visual Editor without any extra code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seamless Visual Editor experience
&lt;/h2&gt;

&lt;p&gt;The integration with Storyblok's Visual Editor is smoother than ever with our improved &lt;code&gt;storyblokEditable&lt;/code&gt; action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;storyblokEditable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$props&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;use:storyblokEditable=&lt;/span&gt;&lt;span class="s"&gt;{blok}&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;{blok.headline}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{blok.text}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures your components are properly highlighted while you edit your content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved error messages
&lt;/h2&gt;

&lt;p&gt;The new error messages will help you solve issues within your integration faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Component "feature" not found. Please register it in storyblokInit:
storyblokInit({
  accessToken: "&amp;lt;your-token&amp;gt;",
  components: {
    "feature": YourComponent
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of generic messages, you'll now receive helpful guidance on how to fix problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved TypeScript support
&lt;/h2&gt;

&lt;p&gt;For TypeScript users, we've enhanced our type definitions for better autocomplete and error checking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SbBlokData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;FeatureBlok&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;SbBlokData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Type-safe blok access&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$props&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;blok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FeatureBlok&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting Started with v5
&lt;/h2&gt;

&lt;p&gt;Ready to upgrade? Here's how to get started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @storyblok/svelte@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update your initialization code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;storyblokInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$lib/Feature.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Grid&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$lib/Grid.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;storyblokInit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;apiPlugin&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Grid&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For components, update your scripts to use the new Svelte 5 syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;storyblokEditable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$props&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;use:storyblokEditable=&lt;/span&gt;&lt;span class="s"&gt;{blok}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;{blok.headline}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{blok.content}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Learn by example
&lt;/h2&gt;

&lt;p&gt;We've created a comprehensive SvelteKit playground that demonstrates all the new features in action.&lt;/p&gt;

&lt;p&gt;Check out our &lt;a href="https://github.com/storyblok/storyblok-svelte" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; to see the example code and learn best practices for building with Storyblok and SvelteKit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking forward
&lt;/h2&gt;

&lt;p&gt;This release reassures our commitment to provide first-class support for modern web frameworks.&lt;/p&gt;

&lt;p&gt;We believe that Svelte's approach to building web applications aligns perfectly with Storyblok's mission to make content management more efficient and enjoyable.&lt;/p&gt;

&lt;p&gt;We're excited to see what you build with this new version of our SDK, and we're already working on more features to improve your Storyblok + Svelte experience.&lt;/p&gt;

&lt;p&gt;For more information, check out our &lt;a href="https://www.storyblok.com/docs" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; or join our &lt;a href="https://discord.gg/jKrbAMz" rel="noopener noreferrer"&gt;Discord community&lt;/a&gt; to share your feedback and questions.&lt;/p&gt;

&lt;p&gt;Happy building!&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>storyblok</category>
    </item>
    <item>
      <title>Storyblok unveils new PHP packages in collaboration with SensioLabs</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Thu, 27 Mar 2025 14:28:40 +0000</pubDate>
      <link>https://dev.to/storyblok/storyblok-unveils-new-php-packages-in-collaboration-with-sensiolabs-khp</link>
      <guid>https://dev.to/storyblok/storyblok-unveils-new-php-packages-in-collaboration-with-sensiolabs-khp</guid>
      <description>&lt;p&gt;At Storyblok, we firmly believe in PHP and the power of open source software. Both have shaped the web as we know it today and continue to be crucial in its evolution.&lt;/p&gt;

&lt;p&gt;That's why we're thrilled to announce that long with our partners &lt;a href="https://sensiolabs.com/" rel="noopener noreferrer"&gt;SensioLabs&lt;/a&gt;, creators of &lt;a href="https://symfony.com/" rel="noopener noreferrer"&gt;Symfony&lt;/a&gt;, we've completely rebuilt our PHP packages from the ground up.&lt;/p&gt;

&lt;p&gt;This collaboration represents more than just an update. It's a complete re-imagining on how PHP developers can interact with Storyblok. By working with SensioLabs, we've ensured these new packages adhere to modern practices, offer excellent Symfony support, and provide a significantly improved developer experience.&lt;/p&gt;

&lt;p&gt;Today, we're announcing four brand-new PHP packages designed to make integrating Storyblok into your projects seamlessly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/storyblok/php-content-api-client" rel="noopener noreferrer"&gt;Content Delivery API Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/storyblok/symfony-bundle" rel="noopener noreferrer"&gt;Symfony Bundle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/storyblok/php-management-api-client" rel="noopener noreferrer"&gt;Management API Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/storyblok/php-tiptap-extension" rel="noopener noreferrer"&gt;Tiptap Extension&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our previous PHP client and associated packages will be deprecated as we move forward with these improved solutions.&lt;/p&gt;

&lt;p&gt;Let's explore each package and what it brings to the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content Delivery API Client
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/storyblok/php-content-api-client" rel="noopener noreferrer"&gt;Content Delivery API Client&lt;/a&gt; is a type-safe PHP SDK designed to retrieve content from Storyblok. It provides an elegant way to interact with your Storyblok space, with built-in support for fetching &lt;strong&gt;stories&lt;/strong&gt;, &lt;strong&gt;links&lt;/strong&gt;, &lt;strong&gt;datasources&lt;/strong&gt;, &lt;strong&gt;tags&lt;/strong&gt;, and &lt;strong&gt;assets&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use this client to easily fetch content for your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\Api\StoriesApi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\Api\StoryblokClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\Api\Request\StoryRequest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StoryblokClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;baseUri&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;https://api.storyblok.com&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'your_storyblok_token'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$storiesApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StoriesApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$storiesApi&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;bySlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'folder/slug'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StoryRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'de'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More advanced features like filtering, pagination, and sorting, are also supported, giving you precise control over the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symfony Bundle
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/storyblok/symfony-bundle" rel="noopener noreferrer"&gt;Storyblok Symfony Bundle&lt;/a&gt; takes integration to the next level for Symfony applications. Developed in direct collaboration with SensioLabs, it leverages the Content Delivery API Client while adding Symfony-specific features like automatic client configuration and Symfony Profiler integration.&lt;/p&gt;

&lt;p&gt;Get started by adding these lines to your &lt;code&gt;config/packages/storyblok.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;storyblok&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;base_uri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%env(STORYBLOK_API_BASE_URI)%'&lt;/span&gt;
  &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%env(STORYBLOK_API_TOKEN)%'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this minimal setup, the bundle handles all the configuration, allowing you to immediately inject and use Storyblok's APIs within your controllers and services.&lt;/p&gt;

&lt;p&gt;The bundle also handles environment-specific configuration, making it easy to switch between development and production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Management API Client
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/storyblok/php-management-api-client" rel="noopener noreferrer"&gt;Management API Client&lt;/a&gt; allows you to programmatically manage your Storyblok content, providing you with a comprehensive set of tools for creating, updating, and organizing content within your spaces.&lt;/p&gt;

&lt;p&gt;This client simplifies complex content management tasks with an intuitive API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\ManagementApi\ManagementApiClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\ManagementApi\Endpoints\StoryApi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\ManagementApi\Data\Story&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\ManagementApi\Data\StoryComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ManagementApiClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$accessToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$storyApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StoryApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$spaceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StoryComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"article-page"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"New Article"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"This is the content"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$story&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Story&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;"An Article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"an-article-slug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$content&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$storyCreated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$storyApi&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$story&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Story created, ID: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$storyCreated&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This package is especially valuable for content migration, bulk operations, and building custom editorial workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  PHP Tiptap Extension
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/storyblok/php-tiptap-extension" rel="noopener noreferrer"&gt;PHP Tiptap Extension&lt;/a&gt; provides an extension specifically designed for Storyblok's rich text fields processing.&lt;/p&gt;

&lt;p&gt;This framework-agnostic package makes rendering rich text fields from Storyblok straightforward and flexible in any PHP project, whether you're using Symfony, Laravel, or any other PHP framework.&lt;/p&gt;

&lt;p&gt;You can easily transform Storyblok's rich text content into HTML with customizable rendering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Tiptap\Editor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Storyblok\Tiptap\Extension\Storyblok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Editor&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'extensions'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Storyblok&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nv"&gt;$editor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Content from your API&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$editor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getHTML&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also allows you to provide your own Block renderer, and it is included in our Symfony Bundle package.&lt;/p&gt;

&lt;p&gt;With all these releases comes a renewed PHP Technology Hub in our official website, a starting point for all your future integrations between your PHP projects and Storyblok.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important note about legacy packages
&lt;/h2&gt;

&lt;p&gt;As part of this launch, the following PHP packages are now entering a deprecation phase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/storyblok/php-client" rel="noopener noreferrer"&gt;storyblok/php-client&lt;/a&gt; (our original PHP Client)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/storyblok/storyblok-php-richtext-renderer" rel="noopener noreferrer"&gt;storyblok/storyblok-php-richtext-renderer&lt;/a&gt; (for handling richtext fields)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your current projects use these packages, don't worry, they will continue to work.&lt;/p&gt;

&lt;p&gt;That said, we strongly encourage all users to move to these new solutions, which offer significant advantages including modern PHP 8+ features, better type safety, and extensive testing.&lt;/p&gt;

&lt;p&gt;We'll be providing migration guides to help with the transition. Support for legacy packages will continue in the meantime, but all new features will exclusively target these new packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  The future ahead
&lt;/h2&gt;

&lt;p&gt;These packages represent a renewed commitment to the PHP ecosystem and the open source community, and we want to express our sincere gratitude to &lt;strong&gt;SensioLabs&lt;/strong&gt; for their expertise and collaboration in this endeavor.&lt;/p&gt;

&lt;p&gt;This release is just the beginning. We're actively working on expanding our PHP support and have exciting plans for the future (to our &lt;strong&gt;Laravel&lt;/strong&gt; users: stay tuned!.&lt;/p&gt;

&lt;p&gt;We invite our wonderful community to try these packages, provide feedback, and contribute to their ongoing development. Get involved at &lt;a href="https://www.storyblok.com/community" rel="noopener noreferrer"&gt;Storyblok Community&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>php</category>
      <category>symfony</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>SymfonyCon Vienna 2024: Recap of our Experience</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Wed, 18 Dec 2024 08:37:30 +0000</pubDate>
      <link>https://dev.to/storyblok/symfonycon-vienna-2024-recap-of-our-experience-mj0</link>
      <guid>https://dev.to/storyblok/symfonycon-vienna-2024-recap-of-our-experience-mj0</guid>
      <description>&lt;p&gt;My personal and professional journey with &lt;strong&gt;PHP&lt;/strong&gt; spans many years, though I've spent recent times focusing on JavaScript frameworks. On the 5th of December, I had the privilege of attending &lt;a href="https://live.symfony.com/2024-vienna-con/" rel="noopener noreferrer"&gt;SymfonyCon&lt;/a&gt; in Vienna with my manager Alex Jover Morales, courtesy of &lt;a href="https://sensiolabs.com/" rel="noopener noreferrer"&gt;SensioLabs&lt;/a&gt;. This conference wasn't just a technical event for me, it was a heartwarming return to the PHP community that has evolved tremendously over the years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conference Highlights
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F021brnmjw4mwnfni2vn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F021brnmjw4mwnfni2vn8.png" alt="SymfonyCon Keynote by Fabien Potencier" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The conference kicked off with an inspiring keynote by &lt;strong&gt;Fabien Potencier&lt;/strong&gt;, the author of &lt;a href="https://symfony.com/" rel="noopener noreferrer"&gt;Symfony&lt;/a&gt;. His presentation focused on &lt;a href="https://twig.symfony.com/" rel="noopener noreferrer"&gt;Twig&lt;/a&gt;, Symfony's powerful templating engine that allows developers to write clean, maintainable templates. The upcoming Twig release introduces exciting features that showcase the continuous innovation in the PHP ecosystem.&lt;/p&gt;

&lt;p&gt;One particularly fascinating technical session dove deep into &lt;strong&gt;HTTP compression algorithms&lt;/strong&gt;. The speaker compared different compression methods including &lt;em&gt;Zstandard&lt;/em&gt; (a high-performance compression algorithm developed by Facebook), &lt;em&gt;Brotli&lt;/em&gt; (Google's compression algorithm optimized for the web), and the widely-used &lt;em&gt;gzip&lt;/em&gt;. Understanding these compression techniques is &lt;strong&gt;crucial for optimizing web application performance&lt;/strong&gt; and reducing bandwidth usage.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://ux.symfony.com/" rel="noopener noreferrer"&gt;Symfony UX&lt;/a&gt; presentation revealed promising statistics and future directions for this frontend framework. For those unfamiliar, &lt;strong&gt;Symfony UX&lt;/strong&gt; is a collection of JavaScript components that integrate seamlessly with Symfony applications, bringing reactive features to traditional server-rendered applications. The numbers shared during the talk suggest a &lt;strong&gt;bright future for this technology&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Platform.sh&lt;/em&gt;, a cloud hosting platform specialized in PHP applications, showcased their latest features, demonstrating how &lt;strong&gt;modern PHP deployment&lt;/strong&gt; can be both powerful and developer-friendly.&lt;/p&gt;

&lt;p&gt;A standout presentation came from Paul Dragoonis about &lt;a href="https://dagger.io/" rel="noopener noreferrer"&gt;Dagger&lt;/a&gt;, a programmable CI/CD engine created by the author of Docker, &lt;strong&gt;Solomon Hykes&lt;/strong&gt;. The talk illustrated how PHP developers can leverage Dagger to define their CI/CD pipelines as code, creating and managing Docker containers programmatically, a significant &lt;strong&gt;step forward for PHP deployment automation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcncqd655vw491ge06ri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcncqd655vw491ge06ri.png" alt="Illustrating Dagger" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "Strict PHP" session resonated strongly with my own philosophy of &lt;strong&gt;writing code for humans&lt;/strong&gt;, not machines. It emphasized the importance of clear, maintainable code that future developers (including ourselves) can easily understand and modify.&lt;/p&gt;

&lt;p&gt;Rob Allen's comparative analysis of &lt;strong&gt;GraphQL&lt;/strong&gt; (a query language for APIs), &lt;strong&gt;REST&lt;/strong&gt; (Representational State Transfer), and &lt;strong&gt;RPC&lt;/strong&gt; (Remote Procedure Call) provided valuable insights into choosing the right API architecture for different use cases.&lt;/p&gt;

&lt;p&gt;This is just a quick overview of some of the talks at the conference to give you an idea of some of the most interesting topics that I found there. There were many more over the two days and across three tracks.&lt;/p&gt;

&lt;h2&gt;
  
  
  SensioLabs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlo3hwh7kbjpkaadmo9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlo3hwh7kbjpkaadmo9j.png" alt="SensioLabs logo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to extend special thanks to &lt;strong&gt;Oskar Stark&lt;/strong&gt; and &lt;strong&gt;Silas Joisten&lt;/strong&gt; from SensioLabs for their incredible hospitality. Our discussions went beyond casual conference chat—we dove deep into technical conversations about PHP, Symfony, and some exciting collaborative projects in the works. &lt;strong&gt;SensioLabs has been using Storyblok&lt;/strong&gt; for their website and recently published &lt;a href="https://sensiolabs.com/blog/2024/sensiolabs-goes-headless-with-storyblok" rel="noopener noreferrer"&gt;a wonderful piece&lt;/a&gt; about their experience. While I can't reveal details yet, we're working on something remarkable together that we're eager to share with the community soon!&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming Full Circle
&lt;/h2&gt;

&lt;p&gt;It was great to be back in the PHP community!&lt;/p&gt;

&lt;p&gt;It felt like coming home. This experience, along with my role as MC at &lt;strong&gt;phpday&lt;/strong&gt; in Italy this year, has reinforced my view that what makes the PHP ecosystem special is the &lt;strong&gt;passion and technical expertise&lt;/strong&gt; of its community members. Physical events like &lt;strong&gt;SymfonyCon&lt;/strong&gt; are priceless because they create chances to make meaningful connections and share knowledge that you just can't get online.&lt;/p&gt;

&lt;p&gt;The PHP community is still growing and coming up with new ideas, guided by the &lt;a href="https://thephp.foundation/" rel="noopener noreferrer"&gt;PHP Foundation&lt;/a&gt; and supported by frameworks like Symfony. Being part of this growth, even for a short time, reminds me why &lt;strong&gt;PHP is still a key part of web development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoee4efu8y4osqskvpf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoee4efu8y4osqskvpf9.png" alt="Storyblok and SensioLabs" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>symfony</category>
      <category>storyblok</category>
      <category>php</category>
      <category>techtalks</category>
    </item>
    <item>
      <title>Announcing React SDK v4 with full support for React Server Components</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Fri, 22 Nov 2024 11:38:42 +0000</pubDate>
      <link>https://dev.to/storyblok/announcing-react-sdk-v4-with-full-support-for-react-server-components-3ld1</link>
      <guid>https://dev.to/storyblok/announcing-react-sdk-v4-with-full-support-for-react-server-components-3ld1</guid>
      <description>&lt;p&gt;The introduction of the &lt;a href="https://nextjs.org/docs/app" rel="noopener noreferrer"&gt;App Router paradigm in Next.js&lt;/a&gt; brought significant changes to the way developers build and structure applications. While it opened the door to exciting features like &lt;a href="https://react.dev/reference/rsc/server-components" rel="noopener noreferrer"&gt;React Server Components (RSC)&lt;/a&gt; and finer control over rendering, it also introduced complexity for packages that needed to seamlessly support both client-side and server-side environments.&lt;/p&gt;

&lt;p&gt;With the release of &lt;a href="https://github.com/storyblok/storyblok-react" rel="noopener noreferrer"&gt;@storyblok/react&lt;/a&gt; version 4.0.0, we are proud to offer full support for React Server Components in Next.js. This update simplifies implementation, enables live preview functionality in our Visual Editor, and ensures robust server rendering, all in a single, unified setup.&lt;/p&gt;

&lt;p&gt;Start using it now with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @storyblok/react@4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you are using &lt;code&gt;@storyblok/react&lt;/code&gt; v3 with App Router, there are some breaking changes. Please continue reading this article to learn how to update your app.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  What's new in @storyblok/react 4.0.0?
&lt;/h3&gt;

&lt;p&gt;Here's a quick rundown of the major improvements in this release:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unified RSC support&lt;/strong&gt;&lt;br&gt;
Previously, React Server Components in Next.js required two different implementations for compatibility. With version 4.0.0, we've streamlined this and consolidated everything into one consistent approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Live preview with Visual Editor&lt;/strong&gt;&lt;br&gt;
Developers using the App Router can now enjoy live preview capabilities directly in the Storyblok Visual Editor, enhancing the development and content editing experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless Server Rendering&lt;/strong&gt;&lt;br&gt;
Leverage the full server rendering capabilities of Next.js for improved performance and scalability of your applications&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Step 1: Initialize the SDK
&lt;/h4&gt;

&lt;p&gt;Start by creating a new file &lt;code&gt;lib/storyblok.js&lt;/code&gt; to initialize the SDK. Make sure to export the &lt;code&gt;getStoryblokApi()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/storyblok.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/Page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Teaser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/Teaser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;apiPlugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;storyblokInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/react/rsc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStoryblokApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;storyblokInit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_ACCESS_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;apiPlugin&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;teaser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Teaser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;getStoryblokApi()&lt;/code&gt; function returns a shared instance of the Storyblok client that works across server and client components.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Wrap Your Application with StoryblokProvider
&lt;/h4&gt;

&lt;p&gt;Next, create a &lt;code&gt;StoryblokProvider&lt;/code&gt; component to enable live editing on the client side. Wrap your entire app with this provider in the &lt;code&gt;app/layout.jsx&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/layout.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;StoryblokProvider&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/StoryblokProvider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RootLayout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoryblokProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StoryblokProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create the &lt;code&gt;StoryblokProvider&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// components/StoryblokProvider.jsx&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getStoryblokApi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/storyblok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;StoryblokProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getStoryblokApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Re-initialize on the client&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the &lt;code&gt;StoryblokProvider&lt;/code&gt; is a client component. This ensures that your client-side components can interact with Storyblok, including live editing in the Visual Editor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Fetch Content and Render Components
&lt;/h4&gt;

&lt;p&gt;In server components, use the &lt;code&gt;getStoryblokApi()&lt;/code&gt; function to fetch content from &lt;code&gt;Storyblok&lt;/code&gt;. Here’s an example &lt;code&gt;app/page.jsx&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getStoryblokApi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/storyblok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StoryblokStory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/react/rsc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoryblokStory&lt;/span&gt; &lt;span class="nx"&gt;story&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;story&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storyblokApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getStoryblokApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;storyblokApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cdn/stories/home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;draft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Use StoryblokServerComponent for server rendering
&lt;/h4&gt;

&lt;p&gt;For rendering components dynamically, always use the &lt;code&gt;StoryblokServerComponent&lt;/code&gt; from &lt;code&gt;@storyblok/react/rsc&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;storyblokEditable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StoryblokServerComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storyblok/react/rsc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nf"&gt;storyblokEditable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blok&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blok&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedBlok&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoryblokServerComponent&lt;/span&gt; &lt;span class="nx"&gt;blok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;nestedBlok&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;nestedBlok&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_uid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;))}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures compatibility with server-side rendering, even if you declare the component as a client component.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;We’re preparing an updated official documentation to make adopting version 4 even smoother. In the meantime, all the essential steps are included in the &lt;a href="https://github.com/storyblok/storyblok-react?tab=readme-ov-file#nextjs-using-app-router" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your feedback and contributions are vital to improving &lt;code&gt;@storyblok/react&lt;/code&gt;! If you have suggestions or issues, feel free to open an &lt;a href="https://github.com/storyblok/storyblok-react/issues" rel="noopener noreferrer"&gt;issue&lt;/a&gt; or contribute directly to the project.&lt;/p&gt;

</description>
      <category>storyblok</category>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How (and why) to contribute to open source</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Thu, 01 Feb 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/how-and-why-to-contribute-to-open-source-1i9a</link>
      <guid>https://dev.to/sparkfabrik/how-and-why-to-contribute-to-open-source-1i9a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the previous post on our blog, Daniela shared her thoughts and experiences on &lt;a href="https://dev.to/sparkfabrik/how-not-to-contribute-to-open-source-77k"&gt;how difficult it can be to contribute to open source&lt;/a&gt;. It was hard for me to review this post. I felt like I had failed as a senior developer, as a mentor, and as a &lt;strong&gt;long-time member of the open source community&lt;/strong&gt;. Then I started thinking about the current state of open source, and what Daniela wrote made sense: to a newcomer, everything seems to be driven by the hype, the star count, the likes, the followers, we have tech influencers, we have tech rockstars giving keynotes at conferences, we have recruiters scanning GitHub profiles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Contributing today is about being visible, not about being helpful. And I think my generation of developers is to blame.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post, I will try to respond to Daniela and all the people who struggle to contribute to open source, and most importantly, I will try to talk about the motivations that should drive our contributions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing to Open Source
&lt;/h2&gt;

&lt;p&gt;First, definitions! Computer scientists have never been good at definitions. We call &lt;em&gt;"artificial intelligence"&lt;/em&gt; something that is not intelligent, and we call &lt;em&gt;"cloud"&lt;/em&gt; something that is on the ground and sometimes &lt;a href="https://news.microsoft.com/source/features/sustainability/project-natick-underwater-datacenter/" rel="noopener noreferrer"&gt;below sea level&lt;/a&gt;. We tried with &lt;strong&gt;Free Software&lt;/strong&gt; and we had to specify &lt;a href="https://www.gnu.org/philosophy/free-sw.en.html" rel="noopener noreferrer"&gt;what we meant by "free"&lt;/a&gt;, and when we realised we needed a more specific definition we created the &lt;strong&gt;Open Source Initiative&lt;/strong&gt; and we had to specify &lt;a href="https://opensource.org/osd/" rel="noopener noreferrer"&gt;what we meant by "open"&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we cannot agree on what open source means, we cannot agree on what it means to contribute to open source.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we stick to the &lt;strong&gt;OSI definition&lt;/strong&gt;, which is derived from Debian's definition of Free Software, we are only talking about how the source code can be accessed, and how the license that governs the distribution of the software should be written.&lt;/p&gt;

&lt;p&gt;But when we talk about open source, we're not just talking about code, or at least I thought we were. We are talking about a way of approaching software, of designing it, developing it, distributing it, spreading it, making it something that benefits everyone. So being a developer in this context means &lt;strong&gt;thinking of software as a common good&lt;/strong&gt;, and then contributing means making it better, and if by better we mean more useful, more accessible, more secure, more powerful, more stable, easier to use, then it is clear that we are not just talking about writing code.&lt;/p&gt;

&lt;p&gt;It would be pointless to list all the non-coding contributions, I just want to point out &lt;strong&gt;participation&lt;/strong&gt; in groups that create guidelines, documentation and translations, those that try to spread best practices, or all the working groups that deal with standardization. But think about how much valuable discussion is generated in GitHub issues, discussion that leads to better software. &lt;strong&gt;None of these activities generate a green square&lt;/strong&gt; in the contribution grid on your GitHub profile, but each one helps improve the entire ecosystem.&lt;/p&gt;

&lt;p&gt;Once we agree on the definition of open source and what it means to contribute, we can move on to the second point in this reflection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why contribute
&lt;/h2&gt;

&lt;p&gt;When I started university in Bologna in the early 2000s, the first community I came into contact with was a kind of Linux user group that organized, in a very informal way, so-called &lt;em&gt;"installation parties"&lt;/em&gt;, i.e. days when some more experienced users would guide us newbies through the first install of a Linux distribution.&lt;/p&gt;

&lt;p&gt;In addition to guiding us through the process of installing Gentoo, which was not a random choice, they would suggest &lt;strong&gt;what to do when we encountered a problem&lt;/strong&gt; or noticed something that could be improved. As you may have guessed, this included posting to our newsgroup, starting a discussion on the official Gentoo Forums, and even using the mailing list. This approach made it natural for me and my fellow travelers to think about &lt;em&gt;communicating with senior members of the community whenever the opportunity arose&lt;/em&gt;, at first just as generators of trivial questions, then more refined, and finally as proposers of solutions or improvements. I never made a commit to the Gentoo codebase, but &lt;strong&gt;I felt useful to the community&lt;/strong&gt; when I answered a colleague's question about how to fix a compile error by creating a symlink to a library that was in the wrong path.&lt;/p&gt;

&lt;p&gt;A few years later &lt;strong&gt;I started working with Drupal&lt;/strong&gt;, still one of the largest and most beautiful free software projects, and interacting with other users on issue trackers, suggesting patches, reporting bugs felt natural to me. Of course, getting the green light from automated tests on an uploaded patch was a good feeling, and when it was merged I felt like I could talk to &lt;em&gt;Dennis Ritchie&lt;/em&gt; as an equal, and so I am no stranger to this reward mechanism.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdp25y6ca2g0rin7c2xxz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdp25y6ca2g0rin7c2xxz.jpg" alt="Drake accepting the Grammy Award with the caption 'I like to thank the reviewers" width="679" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What drove me to contribute, however, &lt;strong&gt;was not the reward&lt;/strong&gt;. It became a necessity, as I was often a few bugs away from delivering a job to a client, and then I felt I had to at least give to others what I had received, so I found myself responding to those who encountered problems I knew how to overcome, or sometimes simply helping by providing my context that might help them understand how to reproduce the bug.&lt;/p&gt;

&lt;p&gt;It was therefore, and still is, &lt;strong&gt;a business motivation&lt;/strong&gt;. &lt;em&gt;"Don't reinvent the wheel"&lt;/em&gt; has been a mantra, building on what others have already introduced and perfected and then making it better, participating in advocacy groups that shape the future of a technology, and many other aspects of the open source world codified and regulated by organizations such as the OSI, but also the &lt;a href="https://www.linuxfoundation.org/" rel="noopener noreferrer"&gt;Linux Foundation&lt;/a&gt; or the &lt;a href="https://www.drupal.org/association" rel="noopener noreferrer"&gt;Drupal Association&lt;/a&gt;, are all aspects that directly impact our work and thus our business.&lt;/p&gt;

&lt;p&gt;Reading Daniela's post &lt;strong&gt;presented me with a completely different experience&lt;/strong&gt;. Talking to her, I realized first of all that she did not find the same conditions in the academic environment that I did, and later that she did not find the communities that I did.&lt;/p&gt;

&lt;p&gt;So the social, utilitarian, and "belonging" motivation that drove me, and I think many others around me, was missing, and &lt;strong&gt;what was left was rewards&lt;/strong&gt;. Of course, recognition had always helped to distinguish an active member of a community from others, but it had never generated &lt;em&gt;such strong pressures&lt;/em&gt; as to drive someone to contribute for the sole purpose of being visible. I seem to see this problem in the desperate search for a project to contribute to, any project, as long as it is popular and publicly acknowledges contributions, and especially if it is on GitHub, which here becomes the social network where a developer's popularity is measured.&lt;br&gt;
&lt;em&gt;(This also removes Drupal from the list of trendy projects...)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gamification, badges, likes, they're nice things and we all love them, let's not be hypocritical, but if they're the main reason people contribute today, then we have a problem, and we probably created it ourselves. We've created an environment where &lt;strong&gt;it's more important to be visible than to be helpful&lt;/strong&gt;, and we've given that message to the new generation of developers, but we're telling them today that those motivations are wrong.&lt;/p&gt;

&lt;p&gt;So I think it's important to reiterate what it means to &lt;strong&gt;do open source&lt;/strong&gt;.&lt;br&gt;
Let's start from that foundation and try to adjust the focus.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to contribute - for real
&lt;/h2&gt;

&lt;p&gt;Let's start with a basic concept: &lt;strong&gt;you don't have to contribute!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are amazing programmers out there who have zero commits to public GitHub repos, yet they work with open source projects every day. Sometimes focusing on work or perhaps a busy personal life &lt;em&gt;makes it difficult to find time to contribute&lt;/em&gt;, and that's not a problem, it shouldn't make us feel guilty.&lt;br&gt;
Helping a colleague use a technology, making it more accessible by spreading it among your peers, are examples of activities that truly benefit the entire ecosystem but do not entitle you to a badge. &lt;/p&gt;

&lt;p&gt;But if, after making all these points, the desire to appear in a project's CHANGELOG remains, because it makes us more desirable in the eyes of a recruiter, or because it makes us feel more important in our community, which are all things I completely understand, then I can try to give some advice on how to contribute.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with what you use&lt;/strong&gt;: You work with libraries or frameworks every day, and by now you know them well; these are the perfect projects to start with. If you need to customize a certain feature to make it more useful for your project, or you find a bug, or you see that some of the documentation could be improved, that's your chance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is no such thing as a "stupid contribution"&lt;/strong&gt;: If you think you have a solution to a problem or an idea for improving something, don't be afraid to share it. If you're not sure, ask for feedback, but know that every contribution is valuable, and the worst thing that can happen is that it's rejected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't be afraid to ask&lt;/strong&gt;: If you don't understand something or aren't sure what to do, ask. There are many channels available, from the official documentation, to the issue tracker, to the community forum, to the chat, to the mailing list. Most (hopefully all) communities are welcoming and eager to help.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't overlook the non-code contributions&lt;/strong&gt;: You can help with translations, documentation, testing (&lt;em&gt;which by the way IS coding...&lt;/em&gt;), or even just by spreading the word about a project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is more than just GitHub&lt;/strong&gt;: Many open source projects are not on GitHub, but they still need love. Just ask Drupal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Join Discussions&lt;/strong&gt;: Issues and Discussions on GitHub are the most popular, but not the only, way to get started. You can learn a lot about a project from these discussions, commenting increases your visibility and participation in the community, and code contributions can often result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Open Source is not just code. It's a way of thinking about software, and contributing means making it better.&lt;br&gt;
You don't &lt;strong&gt;have to&lt;/strong&gt; contribute, and I hope that in the future we can create a more welcoming environment for new contributors, and that the reward mechanism will change to reflect effort and dedication, rather than just commits.&lt;/p&gt;

&lt;p&gt;Thank you for reading this far, and if you have any questions or comments, please feel free to contact me at &lt;a href="https://continuousdelivery.social/@edo" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/edoardodusi/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>community</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>DruBOM: An SBOM for Drupal</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Mon, 29 Jan 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/drubom-an-sbom-for-drupal-3dp6</link>
      <guid>https://dev.to/sparkfabrik/drubom-an-sbom-for-drupal-3dp6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Securing the software supply chain is a hot topic for organizations globally. The recent &lt;em&gt;SolarWinds hack&lt;/em&gt; demonstrated that even the most security-conscious organizations can be vulnerable, and as a result, government agencies and security experts worldwide agreed on the need for standards and best practices to achieve a more secure software ecosystem.&lt;/p&gt;

&lt;p&gt;One fundamental element is the ability to identify all components of a software project, including dependencies, and their versions. This is called a &lt;strong&gt;Software Bill of Materials (SBOM)&lt;/strong&gt;. With this information, organizations can track the components and their versions, and be able to identify and mitigate vulnerabilities.\&lt;br&gt;
There are several initiatives to create standard formats for SBOMs, including &lt;a href="https://cyclonedx.org/" rel="noopener noreferrer"&gt;CycloneDX&lt;/a&gt;, &lt;a href="https://spdx.dev/" rel="noopener noreferrer"&gt;SPDX&lt;/a&gt;, and &lt;a href="https://www.ntia.gov/sbom" rel="noopener noreferrer"&gt;others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are working on a Drupal-specific SBOM called &lt;a href="https://www.drupal.org/project/drubom" rel="noopener noreferrer"&gt;DruBOM&lt;/a&gt;. In this post, we will explain what DruBOM is, how it works, and how you can use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is DruBOM?
&lt;/h2&gt;

&lt;p&gt;First of all, this is a Drupal module, it needs to be downloaded and installed using &lt;em&gt;Composer&lt;/em&gt;, and requires Drupal 9.3 and above or Drupal 10.3 and above.&lt;/p&gt;

&lt;p&gt;To generate the SBOM it integrates &lt;a href="https://github.com/anchore/syft" rel="noopener noreferrer"&gt;Anchore Syft&lt;/a&gt;, so this needs to be installed on the server. &lt;strong&gt;Syft&lt;/strong&gt; is a CLI tool written in Go that analyzes the contents of a container image or directory on the file system and generates an SBOM in various formats, including CycloneDX and SPDX.&lt;/p&gt;

&lt;p&gt;If these requirements are met, DruBOM will generate an SBOM for the Drupal project, including the Drupal core, modules, themes and libraries, as well as PHP and JavaScript dependencies. The default format is CycloneDX, but it can be configured to use other formats supported by Syft.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does DruBOM work?
&lt;/h2&gt;

&lt;p&gt;The initial version of the module is very simple. It detects the Syft binary and calls it passing the Drupal root directory and the output format as parameters, then saves the output to the key-value store with the &lt;code&gt;drubom.sbom&lt;/code&gt; key and the current timestamp.&lt;/p&gt;

&lt;p&gt;You can then download the SBOM, or better yet, use it with automated tools to detect vulnerabilities and/or licensing issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use DruBOM?
&lt;/h2&gt;

&lt;p&gt;The first step is to add the DruBOM module to your Drupal project.\&lt;br&gt;
Run &lt;code&gt;composer require sparkfabrik/drubom&lt;/code&gt; and then enable the module with &lt;code&gt;drush&lt;/code&gt; or via the Drupal administration interface.&lt;/p&gt;

&lt;p&gt;After installing and enabling the module, navigate to &lt;em&gt;Administration » Configuration » System » DruBOM settings&lt;/em&gt; and specify the path of the Syft binary. The binary must be executable by the PHP process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the PHP configuration must allow the use of &lt;code&gt;proc_open()&lt;/code&gt;, which is equivalent to &lt;code&gt;exec()&lt;/code&gt; in terms of security.&lt;/p&gt;

&lt;p&gt;Once the configuration is saved, generate the SBOM by clicking the &lt;strong&gt;Generate SBOM&lt;/strong&gt; button on the settings page or by visiting the &lt;code&gt;/drubom/generate&lt;/code&gt; path with a user who has the necessary permissions. The generated list will be saved on the Drupal DB and can be downloaded by clicking the &lt;strong&gt;Download SBOM&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4o33pw1ow28ryzvltne6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4o33pw1ow28ryzvltne6.jpg" alt="DruBOM administration page" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image: Screenshot of a DruBOM administration page&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can also use the &lt;code&gt;drush drubom:generate&lt;/code&gt; command to generate the SBOM from the command line. To download it, use the &lt;code&gt;drush drubom:download&lt;/code&gt; command.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;The scope of the module is very specific, so we don't expect it to grow much in terms of features. During the &lt;a href="https://www.drupal.org/community/events/drupal-global-contribution-weekend-italy-2024-2024-01-27" rel="noopener noreferrer"&gt;Drupal Contribution Weekend 2024&lt;/a&gt; we improved the documentation and the administration interface, added an integration with the System Status page in Drupal administration, and started integrating with &lt;a href="https://github.com/anchore/grype" rel="noopener noreferrer"&gt;Grype&lt;/a&gt; to also detect vulnerabilities, which is a step forward in terms of security.&lt;/p&gt;

&lt;p&gt;We consider this module to be fully stable and ready for production use, so we encourage you to try it out and give us feedback. If you find any problems, please report them to the &lt;a href="https://www.drupal.org/project/issues/drubom" rel="noopener noreferrer"&gt;issue queue&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>opensource</category>
      <category>security</category>
      <category>sbom</category>
    </item>
    <item>
      <title>Journey to the center of DevRel - Part 1</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Thu, 11 Jan 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/journey-to-the-center-of-devrel-part-1-4k10</link>
      <guid>https://dev.to/sparkfabrik/journey-to-the-center-of-devrel-part-1-4k10</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Developer Relations&lt;/strong&gt;, also known as &lt;strong&gt;DevRel&lt;/strong&gt;, can be defined as the set of activities a company undertakes to build and maintain a relationship with the developer community, both internal and external. It is a relatively new role, and &lt;a href="https://www.youtube.com/watch?v=GZPs8SvpOKA&amp;amp;t=877s" rel="noopener noreferrer"&gt;it might be a bit philosophical&lt;/a&gt; as a job description: you will see that it involves many company departments, from marketing to engineering, from sales to HR.&lt;/p&gt;

&lt;p&gt;Last year we decided to start a DevRel program, and we'd like to share what we've learned. We want to talk about why we did it, the process we followed to get the role and the team up and running, the activities we carried out during the year, and the results we achieved. For those who are considering starting a similar program, and for those who are already doing it and want to compare their experience with ours, we hope this series of articles will be useful.&lt;/p&gt;

&lt;p&gt;Let'start with a bit of history.&lt;/p&gt;

&lt;h2&gt;
  
  
  DevRel through the years
&lt;/h2&gt;

&lt;p&gt;The role of DevRel has been around for a long time, but it is only in recent times that it has become a job title. In the past it was often associated with the role of &lt;strong&gt;evangelist&lt;/strong&gt;, a term many believe was coined by &lt;a href="https://en.wikipedia.org/wiki/Guy_Kawasaki" rel="noopener noreferrer"&gt;Guy Kawasaki&lt;/a&gt; in 1983 when he was working at Apple. In his book &lt;a href="https://guykawasaki.com/books/the-macintosh-way/" rel="noopener noreferrer"&gt;The Macintosh Way&lt;/a&gt; he wrote about it in the context of a software company:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An evangelist.&lt;/strong&gt; A good evangelism program has a champion running it. This person lives and breathes the program. He is the figurehead, guiding light, and godfather for developers. He must thoroughly understand the company's product and technology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And added:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Constant contact.&lt;/strong&gt; Evangelizing developers is like bonding with a child. You need constant contact with them — talking to them on the phone, seeing their products, and taking them to lunch. A good practice is monthly mailings of technical notes, tips, tricks, and examples. Not only do the developers get information, they also get vibes that the company is on top of things and cares about them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdlweyfdos8oe0rb7cap.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdlweyfdos8oe0rb7cap.jpeg" alt="Guy Kawasaki" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image: Guy Kawasaki&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apple sells hardware and software, so the goal of their evangelists was to convince developers to use their products by demonstrating that they were the best choice. Things change when we talk about a service company or a consultancy: we will come back to this later.&lt;/p&gt;

&lt;p&gt;Apple's customers were not just developers, and the same was true for companies such as Microsoft or Adobe, but getting them to advocate for their product was a great way to reach a wider audience. &lt;strong&gt;"The dentist's favourite toothpaste"&lt;/strong&gt; is a claim we are all familiar with, and this is more or less the same strategy.&lt;/p&gt;

&lt;p&gt;In fact, it was popularised in the early 2010s by companies like &lt;a href="https://www.twilio.com/" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt; and &lt;a href="https://newrelic.com/" rel="noopener noreferrer"&gt;New Relic&lt;/a&gt;, which were among the first to hire developer advocates and create a &lt;a href="https://www.twilio.com/blog/developer-relations-at-twilio" rel="noopener noreferrer"&gt;developer relations team&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5ahln4ps9e3rr6l0z10.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5ahln4ps9e3rr6l0z10.jpeg" alt="A Twilio billboard in San Francisco, early 2010s" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image: A Twilio billboard in San Francisco, early 2010s&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The marketing team at these companies understood that they needed to target developers, and when developers are your target audience, traditional marketing strategies don't work, as noted in the seminal book &lt;a href="https://www.devrel.agency/book" rel="noopener noreferrer"&gt;Developer Relations&lt;/a&gt; by Caroline Lewko and James Parton.&lt;/p&gt;

&lt;p&gt;So they started creating content for developers, &lt;strong&gt;speaking at conferences&lt;/strong&gt;, organising meetups, and generally connecting with developers where they were, using their language: our language. This quickly became a trend, and many other companies followed suit: today virtually every major tech company has a DevRel team, as do many startups and even some &lt;a href="https://github.com/ossf/DevRel-community" rel="noopener noreferrer"&gt;open source projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that the role of DevRel is well established, the competition is tough and even for a company that can invest a lot of resources in it, it is not easy to stand out from the crowd. As developers, we not only want to use the best quality tools, the hottest frameworks, the coolest technologies, but we also want to work with companies that share our values, that have a culture, that are inclusive, that &lt;em&gt;make us feel part of a community&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When we started this journey at SparkFabrik, we had all of this in mind: &lt;strong&gt;Developer Relations is about building a community&lt;/strong&gt; that includes our employees and every engineer that comes in contact with us, it is about sharing our principles and vision, and it is about sharing our knowledge and experience with the community, contributing to open source projects and creating content that is useful to others.&lt;/p&gt;

&lt;p&gt;So, we had an understanding of the history of the role in our industry and a somewhat clear idea of what we thought it should be, but since we are a service company and we are not selling a product, even before starting to think about how to do it, we had to answer a fundamental question: &lt;strong&gt;why should we do it?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DevRel?
&lt;/h2&gt;

&lt;p&gt;The first question we asked ourselves was: &lt;strong&gt;why should we do DevRel?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fact that it is a trend in the industry is not a good enough reason to do it, and what works for other companies may not work for us, especially in the Italian market where we could find very few examples to follow.&lt;/p&gt;

&lt;p&gt;Many projects and big decisions at SparkFabrik are the result of a collaborative process, and this was no exception: &lt;em&gt;we started a workshop&lt;/em&gt;! We involved different departments, from marketing to engineering, from sales to HR, because we wanted to identify the impact of the figure in different areas of the company, and from the very beginning we recognised that we needed to divide it into two main categories: &lt;em&gt;external&lt;/em&gt; and &lt;em&gt;internal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can usually apply this to traditional marketing: you want to attract new customers and new talent, and you also want to retain existing customers and employees. So you need to build &lt;em&gt;brand awareness&lt;/em&gt;, establish &lt;em&gt;thought leadership&lt;/em&gt; in the industry, be &lt;em&gt;a place where the best people want to work&lt;/em&gt; and customers want to work with.&lt;/p&gt;

&lt;p&gt;Developers are involved in all these aspects, often including the decision-making process when a company seeks a partner for a new project. By engaging with the community and demonstrating expertise and values, a company's services are more likely to be chosen when solutions are sought.&lt;/p&gt;

&lt;p&gt;In terms of talent acquisition, we agreed that developers tend to favour companies that engage with the community, contribute to open source projects, and offer resources for skill development. By participating in events, supporting hackathons, and maintaining a visible presence in the community, a company can attract potential customers and talented individuals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8y608kmhh8vcsrbeo1ma.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8y608kmhh8vcsrbeo1ma.jpeg" alt="Daniela Bonvini @ angularday 2023" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image: speaking at angularday 2023&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;All of this requires &lt;strong&gt;relations&lt;/strong&gt;. The success of a services company is increasingly intertwined with the developer ecosystem. As technology becomes more complex and interconnected, developers play a key role in driving innovation, service adoption and influencing decisions: by establishing a dedicated DevRel team, we have recognised the importance of strong relationships with the developer community.&lt;/p&gt;

&lt;p&gt;DevRel acts as a &lt;em&gt;bridge&lt;/em&gt; between our company and the developer community, facilitating open communication, gathering feedback and creating a collaborative environment. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Investing in DevRel is becoming an integral part of staying ahead in the competitive technology landscape.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Starting with a question such as "Why do we need something?" is an effective way of articulating the purpose and rationale behind a particular initiative, it resonates with different stakeholders, leads to a &lt;strong&gt;critical thinking&lt;/strong&gt; process of analysis, and sets the stage for &lt;strong&gt;continuous evaluation&lt;/strong&gt;, because as circumstances change the answer may evolve, and periodically revisiting the question ensures that the initiative remains relevant and aligned with the company's objectives.&lt;/p&gt;

&lt;p&gt;Having agreed on the fundamental "why" of implementing a Developer Relations program, we began to discuss more practical aspects of the team: defining &lt;strong&gt;goals and objectives&lt;/strong&gt;, designing &lt;strong&gt;activities and strategies&lt;/strong&gt;, and evaluating &lt;strong&gt;results and impact&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This will be the subject of the next article in this series, so if you are interested in learning more, stay tuned!&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>community</category>
      <category>opensource</category>
    </item>
    <item>
      <title>OSCM: The Open Source Consumption Manifesto</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Mon, 04 Sep 2023 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/oscm-the-open-source-consumption-manifesto-b3o</link>
      <guid>https://dev.to/sparkfabrik/oscm-the-open-source-consumption-manifesto-b3o</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In our previous blog post, we &lt;a href="https://tech.sparkfabrik.com/en/blog/what-is-an-ospo/" rel="noopener noreferrer"&gt;explained what an Open Source Program Office (OSPO) is&lt;/a&gt; and why it is essential for companies that use or produce open source software (OSS). We also provided some guidance on how to create and manage an OSPO, and some useful resources for further learning. If you haven’t read it yet, we recommend you to do so before continuing with this article.&lt;/p&gt;

&lt;p&gt;Just a few days earlier, the &lt;strong&gt;Open Source Security Foundation (OpenSSF)&lt;/strong&gt; published the &lt;a href="https://openssf.org/blog/2023/08/24/join-us-in-adopting-the-open-source-consumption-manifesto/" rel="noopener noreferrer"&gt;Open Source Consumption Manifesto (OSCM)&lt;/a&gt;, a set of core values and guiding principles for software organizations that consume OSS and include it in their software supply chain, and we were thrilled to see that it aligns with our vision.&lt;/p&gt;

&lt;p&gt;The OpenSSF is a cross-industry collaboration that aims to improve the security of OSS, &lt;a href="https://www.infoq.com/news/2020/08/open-source-security-foundation/" rel="noopener noreferrer"&gt;founded in 2020&lt;/a&gt; as part of the &lt;strong&gt;Linux Foundation&lt;/strong&gt; and including among its first members leading companies and organizations, such as Google, Microsoft, IBM, GitHub, and others. The authors of this Manifesto are members of the &lt;a href="https://github.com/ossf/wg-endusers" rel="noopener noreferrer"&gt;OpenSSF End Users Working Group&lt;/a&gt;, which focuses on addressing the needs and challenges of OSS consumers and is chaired by Jonathan Meadows, a senior security engineer, and it was published in August 2023 as a blog post on the OpenSSF website inspired by another famous manifesto, the &lt;a href="https://agilemanifesto.org/" rel="noopener noreferrer"&gt;Agile Manifesto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We believe that after talking about OSPO, it is a good follow-up to talk about OSCM, because both topics are related to the challenges and opportunities of OSS for companies. While OSPO focuses on the organizational and strategic aspects of OSS, and helps companies to manage their relationship with the open source ecosystem, OSCM focuses on the technical and operational aspects, particularly on security.&lt;/p&gt;

&lt;p&gt;Let's see what the OSCM is about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Open Source Consumption Manifesto
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqoig2kbd9s1g10jfki5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqoig2kbd9s1g10jfki5.jpg" alt="OpenSSF Logo" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;OSCM&lt;/strong&gt; is a set of fifteen guidelines for companies and organizations that use OSS (that means, &lt;a href="https://octoverse.github.com/" rel="noopener noreferrer"&gt;almost all of them&lt;/a&gt;) to improve their security posture and reduce the associated risks, and it can be used as a reference to create a &lt;strong&gt;security strategy&lt;/strong&gt; for OSS consumption.&lt;/p&gt;

&lt;p&gt;The blog post that presents it starts reminding us that after the &lt;a href="https://www.wired.com/story/log4j-log4shell/" rel="noopener noreferrer"&gt;Log4Shell&lt;/a&gt; incident, &lt;a href="https://openssf.org/blog/2021/12/16/open-source-foundations-must-work-together-to-prevent-the-next-log4shell-scramble/" rel="noopener noreferrer"&gt;everything changed&lt;/a&gt;. People were talking about it everywhere, measures were taken &lt;a href="https://www.cisa.gov/news-events/cybersecurity-advisories/aa21-356a" rel="noopener noreferrer"&gt;at political level&lt;/a&gt;, and the community was shaken: it was a wake-up call, and it showed that OSS is not immune to security issues, even if it is generally considered &lt;a href="https://ubuntu.com/blog/does-open-source-software-have-the-same-safety-as-proprietary-software" rel="noopener noreferrer"&gt;more secure&lt;/a&gt; than proprietary software.&lt;/p&gt;

&lt;p&gt;But after the initial shock, did something really change? The authors of the Manifesto think that the answer is no, and that companies are not doing enough, using OSS without a clear strategy and without taking the necessary precautions to protect themselves and their customers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In November of 2022, Tenable found 72% of organizations remain vulnerable to Log4Shell. In December of the same year, Wired magazine drew attention to the lack of response as well. And as we drift further from December 2021, it only gets worse. Last month, software developers consumed hundreds of thousands of vulnerable versions of Log4j.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's where the OSCM could make the difference: it's a collection of fifteen principles, or best practices, the result of a long discussion with feedbacks coming from members of different companies and disciplines, and it can help those who decide to adopt it to &lt;strong&gt;change their approach&lt;/strong&gt; to OSS consumption.&lt;/p&gt;

&lt;p&gt;We can summarize it in four core values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Responsibility&lt;/strong&gt;: companies should take responsibility for the consumption of OSS, and security should be considered at every stage of the software development lifecycle (SDLC).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Awareness&lt;/strong&gt;: companies should be aware of the risks and benefits of consuming OSS, and they should be able to make informed decisions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration&lt;/strong&gt;: companies should collaborate with the upstream developers of consumed components, and contribute to the improvement and sustainability of the OSS ecosystem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuos improvement&lt;/strong&gt;: companies should continuously monitor, measure and improve the security of the open source components they consume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please read the &lt;a href="https://github.com/ossf/wg-endusers/tree/main/MANIFESTO" rel="noopener noreferrer"&gt;full text of the Manifesto&lt;/a&gt; for the complete list of principles and guidelines.&lt;/p&gt;

&lt;p&gt;Following the open source philosophy, it is a collaborative effort, so the authors invite everyone to join the working group, adopt it, sign it, and share it with others.&lt;/p&gt;

&lt;h3&gt;
  
  
  OSCM vs security models and frameworks
&lt;/h3&gt;

&lt;p&gt;Both OSPO and OSCM mention the importance of adopting a security strategy for the software supply chain, but they aren't frameworks or models and they don't provide a detailed plan to follow.&lt;/p&gt;

&lt;p&gt;There are established security models, and the OSCM mentions two of them: &lt;strong&gt;SLSA&lt;/strong&gt; and &lt;strong&gt;S2C2F&lt;/strong&gt;. Let's see what they are about.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://slsa.dev/" rel="noopener noreferrer"&gt;SLSA&lt;/a&gt; stands for &lt;strong&gt;Supply chain Levels for Software Artifacts&lt;/strong&gt;, and it is a framework that aims to provide a set of best practices for the software supply chain, with a focus on OSS. It was created by Google, and it is now part of the OpenSSF. It consists of four levels of assurance, from Level 1 to Level 4, that correspond to different degrees of protection against supply chain attacks.&lt;br&gt;
Our CTO Paolo Mainardi mentioned SLSA in &lt;a href="https://www.paolomainardi.com/posts/point-of-no-return-on-managing-software-dependencies/" rel="noopener noreferrer"&gt;a very good article on software supply chain security&lt;/a&gt;, and we also mentioned it in another &lt;a href="https://blog.sparkfabrik.com/en/secure-software-supply-chain-oci-artifacts-on-kubernetes" rel="noopener noreferrer"&gt;article about securing OCI Artifacts on Kubernetes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ossf/s2c2f" rel="noopener noreferrer"&gt;S2C2F&lt;/a&gt; stands for &lt;strong&gt;Secure Supply Chain Consumption Framework&lt;/strong&gt;, and it is a framework developed by Microsoft and contributed to the OpenSSF2. S2C2F is a consumption-focused framework, and it defines a set of practices and a maturity model-based implementation guide to help organizaziont improve the security of their software supply chain.&lt;/p&gt;

&lt;p&gt;These are technical details that are out of the scope of this article, but we think that it is important to mention them because the security strategy of a company should be based on a solid foundation, and these frameworks show that there are already some good starting points, companies don't have to start from scratch. If you want to know more about them or other ways to improve the security of your software supply chain, visit the &lt;a href="https://openssf.org/" rel="noopener noreferrer"&gt;OpenSSF website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The OSCM carries an intention of inclusion. It has changed over the course of our discussions, and we invite your future changes as well. Most of all, we hope the values and principles contained in the OSCM prove helpful. And that it serves as a guide to better open source consumption in your organization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We agree with the OpenSSF: &lt;strong&gt;time is running out&lt;/strong&gt;. The security of the software supply chain is a critical issue, and every company should start to take it very seriously. We covered the OSPO topic in our previous article, and complemented it with the OSCM in this one, to show you that there are concrete and viable solutions that you can start exploring today. Of course this is not the complete picture, and you should always consider your specific context, but we hope that this article can help you to get started.&lt;/p&gt;

&lt;p&gt;We would love to hear your thoughts, so please feel free to contact us via email or social media.&lt;/p&gt;

</description>
      <category>oscm</category>
      <category>security</category>
      <category>softwaresupplychain</category>
      <category>opensource</category>
    </item>
    <item>
      <title>What is an OSPO and why is it important?</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Mon, 28 Aug 2023 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/what-is-an-ospo-and-why-is-it-important-4i</link>
      <guid>https://dev.to/sparkfabrik/what-is-an-ospo-and-why-is-it-important-4i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://opensource.org/osd/" rel="noopener noreferrer"&gt;Open Source&lt;/a&gt; has become a major force in the software industry, powering many of the most popular and innovative applications and platforms in the world. From Linux to Android, from Drupal to WordPress, from Kubernetes to TensorFlow, open source software (OSS) is everywhere. It's estimated that &lt;a href="https://www.synopsys.com/software-integrity/resources/analyst-reports/open-source-security-risk-analysis.html" rel="noopener noreferrer"&gt;96% of all codebases&lt;/a&gt; contain OSS, and that &lt;a href="https://github.blog/2020-09-02-secure-your-software-supply-chain-and-protect-against-supply-chain-threats-github-blog/" rel="noopener noreferrer"&gt;at least 85% of enterprise codebases&lt;/a&gt; are built with open source components.&lt;/p&gt;

&lt;p&gt;In its &lt;a href="https://www.linuxfoundation.org/resources/publications/linux-foundation-annual-report-2022" rel="noopener noreferrer"&gt;Annual Report 2022&lt;/a&gt;, &lt;a href="https://www.linuxfoundation.org/" rel="noopener noreferrer"&gt;The Linux Foundation&lt;/a&gt; celebrates the growth of the global impact of open source, and its increasing adoption by companies and organizations of all sizes. The report also highlights its importance for the future of technology, and the need for companies to have a strategy for managing its use, particularly in the context of compliance, best practices, and security.&lt;/p&gt;

&lt;p&gt;In the whitepaper &lt;a href="https://www.linuxfoundation.org/resources/publications/open-source-missing-data-management-layer" rel="noopener noreferrer"&gt;Open Source:The Missing Data and Management Layer&lt;/a&gt; the LF states that leading tech companies such as Apple, Meta, Amazon and Google have detailed strategies in releasing, contributing and sponsoring OSS projects and conferences, and it's becoming a key part of the business strategy also for companies in other industries, such as Comcast, Bloomberg, and BMW.&lt;/p&gt;

&lt;p&gt;That's why a growing number of companies are creating a team dedicated to managing this relationship, and this team is called &lt;strong&gt;Open Source Program Office (OSPO)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this blog post, we will explain what an OSPO is and why it is essential for companies at any stage of OSS adoption.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an OSPO?
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://www.linuxfoundation.org/research/the-evolution-of-the-open-source-program-office-ospo" rel="noopener noreferrer"&gt;The Evolution of the Open Source Program Office&lt;/a&gt; the &lt;a href="https://todogroup.org/" rel="noopener noreferrer"&gt;TODO Group&lt;/a&gt;, an open community born in 2012 that promotes sustainable OSS adoption and governance within organizations, proposed a Five-Stage OSPO Maturity Model, which describes the evolution of the adoption in companies and can be summarized as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5p00lutd5n37cnema9r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5p00lutd5n37cnema9r.jpg" alt="OSPO maturity model" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stage 0: Adopting Open Source Ad Hoc&lt;/strong&gt;: the company uses OSS, but there is no formal process for managing it. Developers are free to use it to solve problems, but little attention is given to licence compliance or the long-term impact on the company's software supply chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage 1: Providing OSS Compliance, Inventory, and Developer Education&lt;/strong&gt;: the company recognizes that OSS is a key part of the business, and that they need to manage the legal compliance, security practices, developer education, and software inventory. The company creates an OSPO team to manage these activities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage 2: Evangelizing OSS Use and Ecosystem Participation&lt;/strong&gt;: the company recognizes the importance of open source ecosystem for the business, and turn to the OSPOs to help them understand how to contribute to and participate to projects and events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage 3: Hosting OSS Projects and Growing Communities&lt;/strong&gt;: the company hosts or is a primary sponsor of open source projects, dedicating resources to the development of a project and the growth of its community. OSPOs manage the ecosystem, coach project leaders, nurture the community, and seek the assistance of major foundations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage 4: Becoming a Strategic Decision-Making Partner&lt;/strong&gt;: the OSPO is a strategic partner for the company, is involved in all major decisions related to OSS, becomes an internal technology consultant to the CTO and takes a leadership role in benchmarking what can be considered a good OSS project.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;An OSPO serves as the center of competency for an organization's open source operations and structure. It is responsible for defining and implementing strategies and policies to guide these efforts. This can include setting policies around code use, distribution, selection, auditing, contributing, and other key areas; providing education and training to people (inside and outside the organization) involved in open source activities; supporting an organization's efficiency in developing software through encouraging sustainable usage of existing open source components and, where appropriate, contributing enhancements back to these project; when needed, guiding teams with open sourcing their software; ensuring engineering effectiveness; ensuring legal compliance; and promoting and building community engagement.&lt;/p&gt;

&lt;p&gt;-- &lt;a href="https://github.com/todogroup/ospodefinition.org" rel="noopener noreferrer"&gt;TODO Group&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The OSPO is a unit within a company. It can be a whole team or a single person, depending on the size of the company, the level of OSS adoption, and the company's strategy. But why is it important to have an OSPO?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is an OSPO important?
&lt;/h2&gt;

&lt;p&gt;OSS is a key part of the business strategy for many companies, but it also presents many challenges. Let's take a look at some of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  License compliance
&lt;/h3&gt;

&lt;p&gt;Open source software is governed by &lt;a href="https://opensource.org/licenses/" rel="noopener noreferrer"&gt;various licenses&lt;/a&gt; that specify the rights and obligations of the users and contributors. Some licenses are more permissive, such as MIT or Apache, while others are more restrictive, such as GPL or AGPL. It is important to understand and respect the terms and conditions of each license, as well as the compatibility and conflicts between different licenses. Failing to do so can result in &lt;a href="https://www.synopsys.com/blogs/software-security/top-open-source-licenses/" rel="noopener noreferrer"&gt;legal risks&lt;/a&gt;, such as lawsuits, fines, or loss of intellectual property rights.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security practices
&lt;/h3&gt;

&lt;p&gt;Open source software is &lt;a href="https://www.paolomainardi.com/posts/point-of-no-return-on-managing-software-dependencies/" rel="noopener noreferrer"&gt;exposed to a large and diverse user base&lt;/a&gt;, which can increase the chances of discovering and exploiting vulnerabilities. Some open source projects may not have adequate security measures, such as code reviews, testing, encryption, or authentication. Moreover, some components may come from &lt;strong&gt;untrusted or unknown sources&lt;/strong&gt;, which can pose a threat to the software supply chain. Therefore, it is essential to verify and validate the security of the OSS that is used or produced, as well as to monitor and update it regularly to address any security issues or vulnerabilities .&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://openssf.org/" rel="noopener noreferrer"&gt;Open Source Security Foundation&lt;/a&gt; (OpenSSF) is a cross-industry collaboration that brings together the industry's most important open source security initiatives and the companies that support them. The OpenSSF aims to improve the security of OSS by building a broader community, focused on security best practices, vulnerability disclosure, and security tooling, and it can be a valuable resource for companies that want to improve their security practices: it's essential for them to understand and manage the software supply chain, and to have a strategy for managing the use of OSS, and it may soon become a &lt;a href="https://digital-strategy.ec.europa.eu/en/policies/cybersecurity-act" rel="noopener noreferrer"&gt;law requirement&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer education
&lt;/h3&gt;

&lt;p&gt;Adopting OSS requires a different mindset and skillset than proprietary software. Developers need to be familiar with a new set of &lt;a href="https://opensource.com/resources/what-open-source" rel="noopener noreferrer"&gt;values&lt;/a&gt; and &lt;a href="https://github.com/ossf/wg-best-practices-os-developers" rel="noopener noreferrer"&gt;practices&lt;/a&gt;, such as collaboration, transparency, version control, issue tracking, and they need to be proficient in open source tools and platforms that enable communication, documentation, testing and deployment.&lt;/p&gt;

&lt;p&gt;Developers need to understand how to write high-quality and maintainable code that can be easily reused by others, how to contribute to open source projects, and how to participate in open source events. OSS is about community, and developers need to learn how to be part of it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any fool can write code that a computer can understand. Good programmers write code that humans can understand.&lt;/p&gt;

&lt;p&gt;-- &lt;a href="https://martinfowler.com/" rel="noopener noreferrer"&gt;Martin Fowler&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Software inventory
&lt;/h3&gt;

&lt;p&gt;Open source software involves a &lt;a href="https://blog.sonatype.com/software-supply-chain-a-definition-and-introductory-guide" rel="noopener noreferrer"&gt;large and complex network of dependencies and relationships&lt;/a&gt; between different components and projects. It can be challenging to keep track of all the open source software that is used or produced by a company, as well as their sources, versions, licenses, security status, and performance metrics. Having an accurate and up-to-date software inventory is crucial for managing the software lifecycle effectively and efficiently, and in some countries maintaining a Software Bill of Materials (SBOM) is a &lt;a href="https://www.cisa.gov/sbom" rel="noopener noreferrer"&gt;legal requirement&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open source ecosystem
&lt;/h3&gt;

&lt;p&gt;OSS depends on the active and healthy participation of the open source community. The community consists of &lt;a href="https://landscape.cncf.io/" rel="noopener noreferrer"&gt;various stakeholders&lt;/a&gt;, such as developers, users, maintainers, sponsors, foundations, advocates. It is important to engage with the community in a respectful and constructive manner, as well as to contribute back to the community in various ways, such as reporting bugs, providing feedback, submitting patches, donating funds, or hosting events.&lt;/p&gt;

&lt;p&gt;This is not only a matter of good citizenship, but also a matter of business. Participating in the open source ecosystem can help to attract and retain talent, to build trust, reputation, influence, and value for the company. &lt;/p&gt;

&lt;p&gt;By addressing these challenges, an OSPO can help companies reap the benefits of open source software, while mitigating the risks. An OSPO can also help companies evolve and improve their open source maturity over time. At this point it should be clear that since OSS is vital, companies need to establish a structured way to manage it, and that's why an OSPO is so important. But how do you create an OSPO?&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create an OSPO
&lt;/h2&gt;

&lt;p&gt;The TODO Group provides definitions, guides, and case studies of OSPOs already established in various companies. You can take a look at how the OSPO operates &lt;a href="https://todogroup.org/guides/casestudies/microsoft/" rel="noopener noreferrer"&gt;in Microsoft&lt;/a&gt;, for example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6n7x9kksgrxcrei4r6a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6n7x9kksgrxcrei4r6a.jpg" alt="OSPO Landscape" width="800" height="439"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image: &lt;a href="https://landscape.todogroup.org/" rel="noopener noreferrer"&gt;The OSPO Landscape&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The starting point for any company that wants to create an OSPO should be the &lt;a href="https://todogroup.org/guides/create-program/" rel="noopener noreferrer"&gt;TODO guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As with many other strategic decisions, we think that the company needs to clarify &lt;strong&gt;why&lt;/strong&gt; it wants to create an OSPO and what are its expected outcome and benefits. The OSPO should align with the company's vision and values, and be a natural extension of its culture, not an isolated unit. The company should also define the OSPO's &lt;strong&gt;mission&lt;/strong&gt;, &lt;strong&gt;goals&lt;/strong&gt;, and &lt;strong&gt;scope&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The company should also define the structure and the location of the OSPO. It can be centralized or decentralized, depending on the size and culture of the company. It can be a cross-functional team, with members from various departments such as engineering, legal, developer relations or marketing, or maybe it will be a single person reporting to the CTO and advising the other teams on open source matters.&lt;/p&gt;

&lt;p&gt;The OSPO should be responsible for defining the policies and processes, engage with the internal and external community, foster collaboration, provide the tools and resources to participate in projects and events: this unit needs &lt;strong&gt;a good leader&lt;/strong&gt;, with the right skills and experience and a deep understanding of the company's business and culture. A good reference for this role is the TODO Group's &lt;a href="https://todogroup.org/blog/sample-job-req/" rel="noopener noreferrer"&gt;Template Job Posting for Open Source Office Lead&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The process of identifying the goals, the structure and the leader of the OSPO should be transparent, because it will have a central role in the company's strategy and business. It should involve everyone from the CTO to the developers, making sure every input and feedback is taken into account.&lt;/p&gt;

&lt;p&gt;Once the OSPO is established, let's take a look at some of the first activities it should perform.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does an OSPO do?
&lt;/h2&gt;

&lt;p&gt;There is no one-size-fits-all approach to managing open source software, and the OSPO should adapt to the company's needs and culture. However, according to &lt;a href="https://blog.opensource.org/what-is-an-open-source-program-office-and-why-you-should-have-one/" rel="noopener noreferrer"&gt;various sources&lt;/a&gt;, and examples from &lt;a href="https://opensource.microsoft.com/program/" rel="noopener noreferrer"&gt;companies that have already established an OSPO&lt;/a&gt;, we can summarize some common activities that an OSPO should perform as first steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assess the current open source situation&lt;/strong&gt;: it should perform an audit of the company's OSS, to understand what is used and produced, and how it is used and produced. It should also assess the company's open source maturity, to understand what is the current level of adoption and what are the strengths and weaknesses. It could use frameworks such as the OSPO Maturity Model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get executive buy-in and support&lt;/strong&gt;: it should engage with the CTO and the other executives, to make sure they understand the importance of OSS for the company's business, and to get their support and backing for the OSPO's activities. It needs to demonstrate the value proposition and business case of OSS, and the expected costs and benefits. It also needs to secure the necessary resources and budget.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build a cross-functional team&lt;/strong&gt;: even if the OSPO is a single person, &lt;strong&gt;this is not a one-persone job&lt;/strong&gt;, it needs to collaborate with various teams and departments to handle various aspects of open source management. An OSPO would recruit or assign people who have experience and expertise in OSS development, and good communication and collaboration skills, and define a clear reporting structure and authority.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define policies and processes&lt;/strong&gt;: it should define the policies and processes for managing OSS, such as the selection, evaluation, and approval of components, the contribution to projects, the participation in events, the reporting of security vulnerabilities, the management of the software supply chain, the creation and maintenance of a software inventory, the creation and maintenance of a software bill of materials, the training of developers, and so on.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are some of the activities that an OSPO should perform once it is established. Again, the OSPO is not a static or fixed entity, it is dynamic and evolving, because the open source landscape is constantly changing, and the company's strategy can change as well. So &lt;strong&gt;the best advice is to start small&lt;/strong&gt;, and then iterate and improve over time.&lt;/p&gt;

&lt;p&gt;Each company should find its own way, and the OSPO should fit its specific objectives and context.'&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;If you want to learn more about OSPOs, here are some useful resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ospo-news.ghost.io/" rel="noopener noreferrer"&gt;OSPONews from the TODO Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://events.linuxfoundation.org/open-source-summit-europe/about/ospocon/" rel="noopener noreferrer"&gt;OSPOCon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linuxfoundation.org/research/a-deep-dive-into-open-source-program-offices" rel="noopener noreferrer"&gt;A Deep Dive into Open Source Program Offices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxfoundation.eu/newsroom" rel="noopener noreferrer"&gt;Linux Foundation Europe Newsroom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.opensource.org/" rel="noopener noreferrer"&gt;Voices Of Open Source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also wrote about software supply chain security in a previous blog post &lt;a href="https://tech.sparkfabrik.com/en/blog/supply-chain-point-of-no-return/" rel="noopener noreferrer"&gt;The point of no return for software dependencies&lt;/a&gt;, and understanding this topic is essential for OSPOs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we saw that OSS is a valuable asset for companies, but also that using and producing OSS also come with some challenges. To address these challenges effectively and efficiently, a growing number of companies are creating a team dedicated to managing the use of open source software, and this team is called &lt;strong&gt;Open Source Program Office (OSPO)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An OSPO can help companies maximize their investment in OSS, and reduce the risks of using, contributing to, and releasing OSS. It can also help companies evolve and improve their open source maturity, strategy, governance, culture and operations.&lt;/p&gt;

&lt;p&gt;We hope you have enjoyed reading this post and learned something new. If your company already has an OSPO, we would love to hear about your experience, and if you are planning to create an OSPO, we would love to hear about your plans. Feel free to contact SparkFabrik on any of our social channels!&lt;/p&gt;

&lt;p&gt;Thank you for your time and attention. 😎&lt;/p&gt;

</description>
      <category>ospo</category>
      <category>opensource</category>
      <category>opensourceprogramoffice</category>
      <category>security</category>
    </item>
    <item>
      <title>Introduction to Qwik and the Power of Loaders and Actions</title>
      <dc:creator>Edoardo Dusi</dc:creator>
      <pubDate>Mon, 07 Aug 2023 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/introduction-to-qwik-and-the-power-of-loaders-and-actions-33pm</link>
      <guid>https://dev.to/sparkfabrik/introduction-to-qwik-and-the-power-of-loaders-and-actions-33pm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fqwik%2Fqwik-logo.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fqwik%2Fqwik-logo.svg" alt="Qwik logo" width="649" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://qwik.builder.io/" rel="noopener noreferrer"&gt;Qwik&lt;/a&gt; is a JavaScript framework for building web applications with a focus on speed. It's designed to be "the fastest possible first load experience" by prioritizing what's important and loading only what's needed. It achieves this by using a component-level code splitting and optimized server-side rendering. Qwik was created by &lt;a href="https://github.com/mhevery" rel="noopener noreferrer"&gt;Miško Hevery&lt;/a&gt;, the same mind that created the &lt;strong&gt;Angular&lt;/strong&gt; framework at Google, as well as the original &lt;strong&gt;AngularJS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The defining characteristic of Qwik is its instant-on interactivity. Unlike other frameworks, &lt;strong&gt;Qwik is resumable&lt;/strong&gt;, meaning Qwik applications require zero hydration. This allows Qwik apps to be interactive instantly, regardless of the size of the application.&lt;/p&gt;

&lt;p&gt;I recently used Qwik for a talk that I'm giving at &lt;a href="https://www.cometocode.it/" rel="noopener noreferrer"&gt;Come to Code&lt;/a&gt; in Italy. I was impressed by how easy it was to get started with Qwik, how fast it was to build a simple application, and particularly in my brief experience I learned to use two of Qwik's server-side features, &lt;code&gt;routeLoader$&lt;/code&gt; and &lt;code&gt;routeAction$&lt;/code&gt;, and I wanted to share my findings with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Loaders and Actions
&lt;/h2&gt;

&lt;p&gt;One of the key features of Qwik is resumability, and this is achieved by serializing the state of the application into the HTML and sending it to the client. This means that data loading and state changes must happen on the server, and this is where our two functions come in.&lt;/p&gt;

&lt;p&gt;Both are APIs included in Qwik City, a library that provides &lt;strong&gt;server focused features&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;routeLoader$&lt;/code&gt; is used to bind a route to a function that loads data. This is typically used for loading data when the application is bootstrapped or when the state of the application changes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;routeAction$&lt;/code&gt; is used to handle form submissions, to change the state of the application, and to perform any side effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The power of these APIs is their ability to simplify the management of application state and data loading, and the encapsulation of the logic inside specific functions with a separation of concerns that makes the code easier to maintain and reason about. They also allow Qwik to optimize the loading of components and data, and make the application feel faster for the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Let's take a look at an example. Suppose we're building a web application that fetches and displays RSS feeds. We have a function &lt;code&gt;fetchFeeds&lt;/code&gt; that fetches the feeds from a list of URLs, and a function &lt;code&gt;sortAndLimitFeeds&lt;/code&gt; that sorts these feeds by date and limits the result to the latest 10 feeds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchFeeds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feedUrls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch and parse the feeds...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sortAndLimitFeeds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feeds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Sort and limit the feeds...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use &lt;code&gt;routeLoader$&lt;/code&gt; to bind these functions to a URL. This means that when the application is bootstrapped or the state of the application changes, Qwik will automatically call these functions to load the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routeLoader$&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@builder.io/qwik-city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useRssContentLoader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;routeLoader&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feedUrls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://tech.sparkfabrik.com/en/index.xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...];&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feeds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFeeds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feedUrls&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sortAndLimitFeeds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feeds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then use this function in our component to load the data. &lt;code&gt;routeLoader$&lt;/code&gt; returns a &lt;code&gt;Signal&lt;/code&gt;, so we can get the value simply by accessing the &lt;code&gt;value&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRssContentLoader&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./rss-content-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RssContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rssContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRssContentLoader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rssContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;$&lt;/code&gt; at the end of the function is a boundary marker, and it tells the &lt;a href="https://qwik.builder.io/docs/advanced/optimizer/" rel="noopener noreferrer"&gt;Qwik Optimizer&lt;/a&gt; where to break the code to create chunks, for lazy loading.&lt;/p&gt;

&lt;p&gt;The logic inside the function is executed on the server, and the result is serialized and sent to the client. This means that the data is available immediately, and that's why the application is interactive instantly.&lt;/p&gt;

&lt;p&gt;Now let's take a look at &lt;code&gt;routeAction$&lt;/code&gt;. Suppose we want to add a button to our application that allows the user to add a link from a feed to his favorites. We can use &lt;code&gt;routeAction$&lt;/code&gt; to create a function that executes on the server when the user clicks the button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routeAction$&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@builder.io/qwik-city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAddToFavoriteAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;routeAction&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;favoriteLinks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can add the special component &lt;code&gt;Form&lt;/code&gt; to wrap our items list and add a button that calls the &lt;code&gt;useAddToFavoriteAction&lt;/code&gt; function when clicked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAddToFavoriteAction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./add-to-favorite-action&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@builder.io/qwik-city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addToFavoriteAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAddToFavoriteAction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addToFavoriteAction&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rssContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add to favorite&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So &lt;code&gt;routeAction$&lt;/code&gt; is exposing a URL that we can use to trigger an action on the server, via a form submission, and the logic executed on the server is the body of the function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;item&lt;/code&gt; parameter that we pass to the function is an object representing the form data. In this case, it contains the property &lt;code&gt;url&lt;/code&gt; with the &lt;code&gt;value&lt;/code&gt; attribute of the button that was clicked, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://tech.sparkfabrik.com/en/blog/qwik-and-the-power-of-route/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And since under the hood the &lt;code&gt;Form&lt;/code&gt; component uses the native HTML &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element, all of these will work without JavaScript enabled in the browser!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There are many other features in Qwik that I haven't covered in this article, but I hope this gives you a good idea of what Qwik is and how it works. When I started working with Qwik to set up a demo, I was expecting a React-like framework optimized for SSR/SSG, and I knew about its &lt;a href="https://qwik.builder.io/docs/concepts/resumable/" rel="noopener noreferrer"&gt;resumability&lt;/a&gt; concept, but seeing it in action, after developing my simple application and playing with it, looking at its performance, network requests, and the simplicity of the code, I was really impressed. Not to mention the developer experience, which is also great with the &lt;code&gt;qwik new&lt;/code&gt; and &lt;code&gt;qwik add&lt;/code&gt; CLI tools and the debugging in the browser in development mode, the many &lt;a href="https://qwik.builder.io/docs/integrations/" rel="noopener noreferrer"&gt;integrations&lt;/a&gt; that already exist and others that are coming, the wonderful &lt;a href="https://qwik.builder.io/docs/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, and the &lt;a href="https://qwik.builder.io/community/values/" rel="noopener noreferrer"&gt;community&lt;/a&gt; that is growing around it.&lt;/p&gt;

&lt;p&gt;Qwik is ready for production, and I think it's a great choice for building web applications. Maybe I will cover some of its other features in future articles, so stay tuned!&lt;/p&gt;

</description>
      <category>qwik</category>
      <category>javascript</category>
      <category>web</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
