<?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: Daniel Roe</title>
    <description>The latest articles on DEV Community by Daniel Roe (@danielroe).</description>
    <link>https://dev.to/danielroe</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%2F288810%2Fd4da5910-15bb-4916-8cdd-55250e8299e3.jpg</url>
      <title>DEV Community: Daniel Roe</title>
      <link>https://dev.to/danielroe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danielroe"/>
    <language>en</language>
    <item>
      <title>The virtuous circle</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Tue, 03 Mar 2026 12:34:45 +0000</pubDate>
      <link>https://dev.to/danielroe/the-virtuous-circle-2coo</link>
      <guid>https://dev.to/danielroe/the-virtuous-circle-2coo</guid>
      <description>&lt;p&gt;The virtuous circle is the most powerful pattern in developer tooling. And it's the myth of the 10x developer that makes it hard to see.&lt;/p&gt;

&lt;p&gt;I've been thinking about this a lot recently, because of &lt;a href="https://npmx.dev" rel="noopener noreferrer"&gt;npmx&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 10x developer
&lt;/h2&gt;

&lt;p&gt;In a &lt;a href="https://dl.acm.org/doi/10.1145/362851.362858" rel="noopener noreferrer"&gt;1968 study&lt;/a&gt;, researchers found a gap between the most productive developers and the &lt;em&gt;average&lt;/em&gt; developer. The 'best' developers were producing 10 times more output than the average.&lt;/p&gt;

&lt;p&gt;Something about this number stuck. Many of us believe that there are 10x developers out there. We either want to be a 10x developer or we feel inadequate because we feel we aren't.&lt;/p&gt;

&lt;p&gt;Or maybe we simply enjoy imagining our heroes as 10x developers.&lt;/p&gt;

&lt;p&gt;After all, there are rock stars out there – both in open source and within our companies.&lt;/p&gt;

&lt;p&gt;But I think it's unhelpful. And I think it misses the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building together
&lt;/h2&gt;

&lt;p&gt;There are a couple of interesting studies out there that suggest that &lt;a href="https://hci.stanford.edu/publications/2009/PrototypingEfficacy-CC09/PrototypingEfficacy-CC09.pdf" rel="noopener noreferrer"&gt;iteration beats one-off design&lt;/a&gt; (at least, under time constraint), or that &lt;a href="https://hci.stanford.edu/publications/2010/parallel-prototyping/ParallelPrototyping2010-final.pdf" rel="noopener noreferrer"&gt;working in parallel produces better results&lt;/a&gt; than a traditional serial waterfall. And there is research to show that &lt;a href="https://www.pnas.org/doi/10.1073/pnas.2101062118" rel="noopener noreferrer"&gt;teams outperform individuals on complex tasks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This doesn't refute the idea that some individuals might be 10x developers. But it does suggest that looking for individuals isn't the best approach.&lt;/p&gt;

&lt;p&gt;We would be better off finding highly motivated teams, who are able to iterate and build together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The virtuous circle
&lt;/h2&gt;

&lt;p&gt;I started thinking about the idea for npmx late one night (I couldn't sleep, and spotted a Slack message that nerd-sniped me). I &lt;a href="https://bsky.app/profile/danielroe.dev/post/3md3cmrg56k2r" rel="noopener noreferrer"&gt;posted on Bluesky&lt;/a&gt; to ask for people's wishlist for &lt;a href="https://npmjs.com" rel="noopener noreferrer"&gt;https://npmjs.com&lt;/a&gt; – and started building npmx almost immediately. By the next day, I had an MVP.&lt;/p&gt;

&lt;p&gt;But the real key was the response on Bluesky. Everyone wanted something. Everyone wanted to make &lt;a href="https://npmjs.com" rel="noopener noreferrer"&gt;https://npmjs.com&lt;/a&gt; better.&lt;/p&gt;

&lt;p&gt;And, seeing that response, I messaged a friend.&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%2Fpsaxj31wi2hro0z4qkw2.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%2Fpsaxj31wi2hro0z4qkw2.png" alt="A screenshot of me asking: want to collab with npmx.dev? I think it could be v big (because so many of us feel the pain)" width="800" height="731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as we started reaching out to friends – and then to people we respected on Bluesky and elsewhere – it became clear.&lt;/p&gt;

&lt;p&gt;This was a project where the virtuous circle would work. &lt;/p&gt;

&lt;p&gt;What's a virtuous circle? Well, it's the positive form of a vicious circle.&lt;/p&gt;

&lt;p&gt;In our case, the audience for &lt;a href="https://npmx.dev" rel="noopener noreferrer"&gt;https://npmx.dev&lt;/a&gt; are the same people who can contribute and build it. That means, if we want to improve our experience using the npm registry, we hold all the tools to make it better. The better it gets, the more we use it – and the more people who might contribute and make it better.&lt;/p&gt;

&lt;p&gt;The great thing about this is that we aren't being driven by a corporate agenda. We're not being limited by lack of funding. npmx will continue to grow to make our lives as developers better, incrementally, in parallel – and as a team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where we're going
&lt;/h2&gt;

&lt;p&gt;I don't think we need 10x developers to build great things. I think we need 10x &lt;em&gt;teams&lt;/em&gt; – groups of people who care about the same problem, who iterate together, and who make each other better.&lt;/p&gt;

&lt;p&gt;npmx is community-driven and open source, and we have open doors for anyone to contribute. If you've ever felt the pain of navigating the npm registry, you already have something to offer.&lt;/p&gt;

&lt;p&gt;Come and build with us.&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>The golden thread</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Wed, 14 Jan 2026 23:03:06 +0000</pubDate>
      <link>https://dev.to/danielroe/the-golden-thread-1n69</link>
      <guid>https://dev.to/danielroe/the-golden-thread-1n69</guid>
      <description>&lt;p&gt;There is a story I read as a child, in &lt;a href="https://en.wikipedia.org/wiki/The_Book_of_Virtues" rel="noopener noreferrer"&gt;&lt;em&gt;The Book of Virtues&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It goes like this: a boy is given – by a mysterious woman – a ball of golden thread, with a single thread poking out.&lt;/p&gt;

&lt;p&gt;He discovers that when he pulls the thread, time passes. Pull it a little, and a painful exam is over. Pull a little more – and the school year is done.&lt;/p&gt;

&lt;p&gt;As the story unfolds, the boy's life passes faster and faster. He jumps from success to success without effort. And then waking one day, old, he realises that life has run through his fingers.&lt;/p&gt;

&lt;p&gt;It's not too dissimilar from the more grisly fable of the butterfly struggling to get out of its chrysalis. A child helps it by tearing the chrysalis open, only to find that without the effort of fighting its way out, its lungs never fully develop and it dies.&lt;/p&gt;

&lt;p&gt;The moral of both stories is that there is &lt;em&gt;worth&lt;/em&gt; in what seem to be boring or painful experiences. Effort has intrinsic value.&lt;/p&gt;

&lt;p&gt;We would be diminished if we always skipped directly to success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Winning immediately
&lt;/h2&gt;

&lt;p&gt;I certainly have spent a lot of my life looking to skip directly to success. As, probably, have we all.&lt;/p&gt;

&lt;p&gt;It surprised me recently to discover that 'former gifted kids' report a set of similar experiences. Many had effortless success in early life. Validation from teachers, parents and others. Later on, they start to feel demotivated or aimless as life gets more complicated and 'success' feels harder to achieve.&lt;/p&gt;

&lt;p&gt;We become failure-averse – reluctant to try new or difficult things for fear that we won't immediately achieve the success we want.&lt;/p&gt;

&lt;p&gt;It seems that something in our psyche needs difficulty. Or, more precisely, to overcome difficulty.&lt;/p&gt;

&lt;p&gt;Maybe by learning the feeling of persisting through difficulty to an eventual success, we become more confident to tackle new and more difficult problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Effort and grift
&lt;/h2&gt;

&lt;p&gt;Grift, on the other hand, is diametrically opposed to effort. Almost every grift involves the promise of something for nothing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Spend pennies, get a guaranteed return with no risk."&lt;/li&gt;
&lt;li&gt;"Purchase my template, and you'll have a profitable SaaS."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Some 'fear of missing out' comes from listening to grifters. We feel we're late to the gold rush.)&lt;/p&gt;

&lt;p&gt;This is absolutely happening in the AI space.&lt;/p&gt;

&lt;p&gt;Sometimes it's unintentional. People are excited about what's possible. ("I built this whole app with an agent – it did it all itself!")&lt;/p&gt;

&lt;p&gt;Sometimes it's to sell a product.&lt;/p&gt;

&lt;p&gt;Regardless, if we listen to some of these stories, we might see AI as 'value for nothing'. Why not vibe code your way to success? Or build your network with your new LinkedIn auto-responder bot?&lt;/p&gt;

&lt;p&gt;Of course we want to maximise our leverage. We want to get the most possible value out of the effort we put in. But we can't avoid this one truth: the value we receive is &lt;em&gt;always&lt;/em&gt; a function of the value we contribute.&lt;/p&gt;

&lt;p&gt;That might be anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the vision that brings people together&lt;/li&gt;
&lt;li&gt;the effort of showing up daily&lt;/li&gt;
&lt;li&gt;the genius idea (though rarely is the &lt;em&gt;idea&lt;/em&gt; the most precious thing)&lt;/li&gt;
&lt;li&gt;the kindness and care that makes a team work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Value isn't replaceable.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better story
&lt;/h2&gt;

&lt;p&gt;I can't but help think that we might as well tell the story of &lt;em&gt;The Developer and the Golden LLM&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One day a developer meets a wizened old man in the forest.&lt;/p&gt;

&lt;p&gt;"My name is Claude," he introduces himself. "I wish to give you this golden LLM. You can ask it any question at all and it will answer it for you. Write code, edit your tweets, evaluate your boyfriend's texts."&lt;/p&gt;

&lt;p&gt;With joy, he receives the golden LLM. Day by day he uses it. First, a little. Then, more and more. Soon it seems that he barely touches any task without directly bringing out the golden ball.&lt;/p&gt;

&lt;p&gt;But as the years pass, he realises he can't recall much of what he's shipped. Bugs surface that he &lt;em&gt;must&lt;/em&gt; have introduced – but he has no memory of them. He has more followers than ever on Twitter, but he's not sure any of them actually want to hear what he has to say.&lt;/p&gt;

&lt;p&gt;One day, he sets out to create a side project on a plane and finds himself just staring at the screen, unable to code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the original story, the boy chooses to go back and live his life again, but without the ball of golden thread.&lt;/p&gt;

&lt;p&gt;For us, turning back time isn't an option.&lt;/p&gt;

&lt;p&gt;But we &lt;em&gt;can&lt;/em&gt; learn from the story.&lt;/p&gt;

&lt;p&gt;How we approach these tools makes a huge difference. If we treat them as a substitute for effort, we're barely a step away from grift – and I really believe we'll wake up one day, completely hollow.&lt;/p&gt;

&lt;p&gt;But that doesn't have to be our story. We don't have to treat AI as a zero-effort shortcut to success.&lt;/p&gt;

&lt;p&gt;We can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;treat generated code as ephemera rather than the finished product&lt;/li&gt;
&lt;li&gt;review every line, increasing our skillset at the same time&lt;/li&gt;
&lt;li&gt;solve new problems and build new instincts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI serves us as a &lt;a href="https://roe.dev/blog/using-ai-in-open-source" rel="noopener noreferrer"&gt;force multiplier&lt;/a&gt;, augmenting our own agency and making the most of our own effort, hard work and value, not by replacing it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>life</category>
    </item>
    <item>
      <title>Diversity, equity and inclusion</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Mon, 10 Mar 2025 14:44:09 +0000</pubDate>
      <link>https://dev.to/danielroe/diversity-equity-and-inclusion-69g</link>
      <guid>https://dev.to/danielroe/diversity-equity-and-inclusion-69g</guid>
      <description>&lt;p&gt;This really shouldn't need to be written:&lt;/p&gt;

&lt;p&gt;I'm in favour of diversity, equity and inclusion.&lt;/p&gt;

&lt;p&gt;Let me explain why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Politics
&lt;/h2&gt;

&lt;p&gt;But first, this isn't political.&lt;/p&gt;

&lt;p&gt;By that, I mean it's not party-political. What I think and say about diversity, equity and inclusion isn't because of my political views.&lt;/p&gt;

&lt;p&gt;Rather, I'm writing about &lt;em&gt;values&lt;/em&gt; - core beliefs. Values are the things that should shape our politics. They should affect who we vote for and who we align ourselves with.&lt;/p&gt;

&lt;p&gt;For that reason, I think it's dangerous when your politics starts shaping your values. That can lead to extremism and tribalism - and demonising people who vote differently. My opinion? We should talk less about politics, and more about values - even if that's dismissed as 'political'.&lt;/p&gt;

&lt;p&gt;Hold your politics lightly but your values tightly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Direction
&lt;/h2&gt;

&lt;p&gt;In fact, I would be remiss &lt;em&gt;not&lt;/em&gt; to speak about values.&lt;/p&gt;

&lt;p&gt;Values shape the direction of projects and people. They also shape the culture of open source communities. They make the difference both in where we end up and what the journey there is like.&lt;/p&gt;

&lt;p&gt;As a leader, whatever you say matters.&lt;/p&gt;

&lt;p&gt;Even if you say nothing. Especially if you say nothing.&lt;/p&gt;

&lt;p&gt;So here are a few reasons why diversity, equity and inclusion will be core values in any project I'm involved with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diversity
&lt;/h2&gt;

&lt;p&gt;I can think of no better way to stop growing as a person than to be always around people who are just like me.&lt;/p&gt;

&lt;p&gt;Being around people who are not the same as us broadens and strengthens us.&lt;/p&gt;

&lt;p&gt;Not to mention, it's more fun.&lt;/p&gt;

&lt;p&gt;There's also another very real way diversity is a necessity in open source.&lt;/p&gt;

&lt;p&gt;In building any product - or open source project! - one of the most valuable skills is &lt;em&gt;empathy&lt;/em&gt;: the ability to place yourself in the position of someone using your product.&lt;/p&gt;

&lt;p&gt;That is true for developer tooling too. It's a bit easier because we're developers already - we're much closer to the 'user'. In a sense we can build for ourselves.&lt;/p&gt;

&lt;p&gt;But there's diversity amongst developers. We have different needs.&lt;/p&gt;

&lt;p&gt;If we take that seriously - if we value empathy - then the value of diversity within a team isn't controversial at all.&lt;/p&gt;

&lt;p&gt;Sometimes diversity and capability are seen as opposite poles. And that's an insult, honestly, that I won't even bother responding to. If you think that, please take a long hard look in the mirror.&lt;/p&gt;

&lt;p&gt;It should go without saying, but I would &lt;em&gt;love&lt;/em&gt; to see increased diversity of backgrounds in the Nuxt team and contributors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Equity
&lt;/h2&gt;

&lt;p&gt;There's a very strong sense of fairness in open source. Projects like Nuxt are community-based. It really matters how things feel and how people are treated.&lt;/p&gt;

&lt;p&gt;It's important to recognise that we don't all start from the same place. Making adjustments to accommodate differences isn't special treatment - it's creating a level playing field.&lt;/p&gt;

&lt;p&gt;If people are treated badly, or unfairly, then we need to make it right. Please don't be silent about it. I've written &lt;a href="https://roe.dev/blog/governance-and-abuse" rel="noopener noreferrer"&gt;a little bit about it&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inclusion
&lt;/h2&gt;

&lt;p&gt;I'm an outsider to the tech world, even if I'm privileged in many other ways. I know what it was to be welcomed in. I'd like that to be true for many more people too. 'Freely you have received, freely give,' are words that mean a lot to me. Plus, half of the fun of open source is in working collaboratively.&lt;/p&gt;

&lt;p&gt;So from my point of view, open source is and should be &lt;em&gt;open&lt;/em&gt;. Come on in! We'd love to have you. And &lt;a href="https://roe.dev/blog/open-invitation" rel="noopener noreferrer"&gt;have a chat with me&lt;/a&gt; if that would be helpful!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why write this?
&lt;/h2&gt;

&lt;p&gt;Nuxt, like many other projects, adheres to the &lt;a href="https://www.contributor-covenant.org/" rel="noopener noreferrer"&gt;Contributor Covenant&lt;/a&gt;. You can read our code of conduct &lt;a href="https://github.com/nuxt/.github/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We're not unique in caring about diversity, equity and inclusion.&lt;/p&gt;

&lt;p&gt;I'm not winning any friends by writing this. People who like me already probably know where I stand on this. And those who disagree might find me overbearing.&lt;/p&gt;

&lt;p&gt;But I think it's important to speak clearly about this for several reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I want people of all backgrounds to know that you are welcome in projects I'm involved with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'Diversity, equity and inclusion' are being rejected at government and corporate levels. In places they are &lt;em&gt;banned terms&lt;/em&gt;. Silence in the face of this becomes implicit acceptance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I want people to reconsider letting their values be shaped by their politics. Whatever country you live in, and whoever you vote for there, this is more important.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The strength of open source has always been its community. And the strongest communities are those where everyone can contribute their unique perspectives and talents.&lt;/p&gt;

&lt;p&gt;I would be very glad of your thoughts on how we can better implement these values.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>diversity</category>
      <category>inclusion</category>
    </item>
    <item>
      <title>Zero sum games</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Tue, 04 Feb 2025 11:11:47 +0000</pubDate>
      <link>https://dev.to/danielroe/zero-sum-games-h61</link>
      <guid>https://dev.to/danielroe/zero-sum-games-h61</guid>
      <description>&lt;p&gt;Open source is about mutual giving. So how does that square with commercial open source? Or building a for-profit product &lt;em&gt;on top&lt;/em&gt; of an open source project?&lt;/p&gt;

&lt;p&gt;There are plenty of examples of projects that (at some point) push back against third-party commercialisation, whether that's &lt;a href="https://investors.mongodb.com/news-releases/news-release-details/mongodb-issues-new-server-side-public-license-mongodb-community" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; or &lt;a href="https://www.elastic.co/blog/license-change-clarification" rel="noopener noreferrer"&gt;Elasticsearch&lt;/a&gt;. And it's also not uncommon to see open source developers become jaded, disillusioned and bitter that the money being made using their software isn't flowing back to them.&lt;/p&gt;

&lt;p&gt;In recent days, the most obvious example of that is Matt Mullenweg of WordPress, whose &lt;a href="https://www.theverge.com/2024/10/4/24262232/matt-mullenweg-wordpress-org-wp-engine" rel="noopener noreferrer"&gt;lawsuit against WP Engine&lt;/a&gt; seems to stem from a frustration that they are profiting from something he has built.&lt;/p&gt;

&lt;p&gt;If I can communicate one thing on my own behalf here, it's this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Flourish! Build a company if that's your thing. Bless the people who work for you. Make money. Enjoy! No strings attached.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By default, if you are building with Nuxt, &lt;strong&gt;I want you to succeed&lt;/strong&gt;.&lt;br&gt;
If you are a third-party provider with a great Nuxt module or integration, &lt;strong&gt;I want you to succeed&lt;/strong&gt;.&lt;br&gt;
If you are creating a course to teach other developers, &lt;strong&gt;I want you to succeed&lt;/strong&gt;.&lt;br&gt;
If you're a consultant helping people make great, performant Nuxt sites, &lt;strong&gt;I want you to succeed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;... and I don't want that goodwill to be conditional on sponsorship or 'paying Nuxt back'. Nor do I care if you are 'competing' with me (or any of the Nuxt team).&lt;/p&gt;

&lt;p&gt;Here's why I feel that way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open source is a community project&lt;/strong&gt;. I can't possibly feel bitter about not getting 'what I deserve' when it's not me, but a whole group of talented and lovely people who have made it possible. In many cases - including my own - we have done so &lt;em&gt;because&lt;/em&gt; there were no strings attached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compensation doesn't follow value&lt;/strong&gt;. If I start trying to find my value in how many donations or sponsorships I get, I'll destroy my own mental health. Better to let go of that &lt;em&gt;expectation&lt;/em&gt;. And, where I need compensation, find it by seeking it out in consultancy, entrepreneurship, retainer or employment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Success is contagious&lt;/strong&gt;. The more commercial projects succeed, building on top of open source work, the more the whole ecosystem benefits. Jobs are created. Conferences flourish. Educators produce articles and videos. More people contribute. More companies are created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Someone recently wrote to me via an &lt;a href="https://bsky.app/hashtag/ama?author=danielroe.dev" rel="noopener noreferrer"&gt;#ama&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should I feel bad for trying to make a for-profit product using Nuxt ecosystem? It's unbelievable how many great free things it offers, it makes me feel kinda bad trying to use it for my own benefit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My answer is pretty simple: Don't feel bad. Build your product - and flourish!&lt;/p&gt;




&lt;p&gt;&lt;small&gt;∗ I'm speaking about &lt;em&gt;my&lt;/em&gt; feelings, but if anyone should be 'paid back' for Nuxt it would probably be Sebastien &amp;amp; Alex Chopin, who created it in the first place.&lt;/small&gt;&lt;/p&gt;

</description>
      <category>profit</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Today is your day</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Tue, 04 Feb 2025 11:11:44 +0000</pubDate>
      <link>https://dev.to/danielroe/today-is-your-day-19m</link>
      <guid>https://dev.to/danielroe/today-is-your-day-19m</guid>
      <description>&lt;p&gt;What a year.&lt;/p&gt;

&lt;p&gt;Reflection isn't my strong suit. I think. But I wish it were more part of my life. So I thought I'd try to piece together … part of …  my story in 2024.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oh, the places you'll go!
&lt;/h2&gt;

&lt;p&gt;This year, I've attended conferences or meetups in Toronto, Prague, Seattle, Amsterdam, Glasgow, Middlesbrough, Bonn, Portlaoise, Athens, New Orleans, San Francisco, London and Edinburgh. I've also enjoyed making &lt;a href="https://www.edinburghjs.org/" rel="noopener noreferrer"&gt;EdinburghJS&lt;/a&gt; a regular part of my life.&lt;/p&gt;

&lt;p&gt;&lt;a href="/img/today-is-your-day/flighty-passport.png" class="article-body-image-wrapper"&gt;&lt;img src="/img/today-is-your-day/flighty-passport.png" alt="Flighty 'passport'"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've loved every moment of it. Not the places, so much as the &lt;em&gt;people&lt;/em&gt;. The tech world is amazing - but the greatest part for me is meeting people I respect and collaborate with.&lt;/p&gt;

&lt;p&gt;I also find that travelling can be productive. I love coding on the plane or train - it's often joyously focused - and I always notice bursts of creativity after conferences.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next year, I'd like to widen the circle&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd like to see more folk I don't already know. That will mean answering CFPs at conferences further afield. Recommendations welcome 🙏&lt;/p&gt;

&lt;h2&gt;
  
  
  You’ll be seeing great sights!
&lt;/h2&gt;

&lt;p&gt;This was the second year that I have &lt;a href="https://nuxt.com/blog/vision-2023" rel="noopener noreferrer"&gt;led Nuxt&lt;/a&gt;. It's been exhilarating to see how things have grown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://2024.stateofjs.com/en-US/libraries/meta-frameworks/" rel="noopener noreferrer"&gt;&lt;br&gt;
&lt;img src="/img/today-is-your-day/state-of-js-nuxt-positivity.png" alt="A chart of meta-framework positivity, showing Nuxt rising to #4 in 2024, from #7 in 2023."&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're rising in retention, positivity and awareness compared to other meta-frameworks. I don't claim credit for that - but it's a pleasure to be a part of the community that makes that possible.&lt;/p&gt;

&lt;p&gt;This isn't a zero-sum game. Nuxt doesn't 'lose' when other frameworks do well. I want to see our community characterised by the kind of relentless kindness that (I firmly believe) will in the end lead to continued growth and success.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/unjs" rel="noopener noreferrer"&gt;unjs project&lt;/a&gt; is an example of our commitment to go further, together, and I'm delighted to see &lt;a href="https://analogjs.org/" rel="noopener noreferrer"&gt;other&lt;/a&gt; &lt;a href="https://start.solidjs.com/" rel="noopener noreferrer"&gt;frameworks&lt;/a&gt; &lt;a href="https://tanstack.com/start" rel="noopener noreferrer"&gt;are&lt;/a&gt; joining us in building on top of &lt;a href="https://nitro.build/" rel="noopener noreferrer"&gt;Nitro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've spent most of this year focusing on improving the &lt;em&gt;stability&lt;/em&gt; and &lt;em&gt;trustworthiness&lt;/em&gt; of the Nuxt ecosystem in the run-up to the release of Nuxt v4, but I do feel a bit lost in the details.&lt;/p&gt;

&lt;p&gt;I have managed to launch a few projects, from &lt;a href="https://github.com/nuxt/fonts" rel="noopener noreferrer"&gt;Nuxt Fonts&lt;/a&gt;, &lt;a href="https://github.com/unjs/unifont" rel="noopener noreferrer"&gt;unifont&lt;/a&gt;, &lt;a href="https://github.com/danielroe/page-speed.dev" rel="noopener noreferrer"&gt;page-speed.dev&lt;/a&gt; to smaller ones like &lt;a href="https://github.com/danielroe/oxc-walker" rel="noopener noreferrer"&gt;oxc-walker&lt;/a&gt;, &lt;a href="https://github.com/unjs/impound" rel="noopener noreferrer"&gt;impound&lt;/a&gt;, &lt;a href="http://github.com/unjs/errx" rel="noopener noreferrer"&gt;errx&lt;/a&gt;, &lt;a href="https://github.com/danielroe/zero-vue" rel="noopener noreferrer"&gt;zero-vue&lt;/a&gt;, &lt;a href="https://github.com/danielroe/nuxt-workers" rel="noopener noreferrer"&gt;nuxt-workers&lt;/a&gt; or &lt;a href="https://github.com/danielroe/nuxt-rebundle" rel="noopener noreferrer"&gt;nuxt-rebundle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nevertheless it feels like my idea list is full to overflowing, and I would &lt;em&gt;love&lt;/em&gt; more time to create features or launch new projects! ✨&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next year, I want to do more &lt;em&gt;pioneering&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  You’re off and away!
&lt;/h2&gt;

&lt;p&gt;I &lt;em&gt;love&lt;/em&gt; coding. It's fun and my hobby. I don't have an objective to be 'active' on GitHub every day. But, as it happens, I have been.&lt;/p&gt;

&lt;p&gt;That's a side-effect of doing something that I enjoy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-wrapped.com/profiles/danielroe" rel="noopener noreferrer"&gt;&lt;br&gt;
&lt;img src="/img/today-is-your-day/git-wrapped.png" alt="Git Wrapped profile for @danielroe, showing my 2024 Year in Code, with 👑 Universal Rank: Top 0.5%, ⚡️ Longest Streak: 366 days, 🏆 Total Commits: 13,020, 📅 Most Active Month: December, 📊 Most Active Day: Tuesday, ⭐ Stars Earned: 81,796, 🚀 Top Language: TypeScript, 🪐 Power Level: God Mode"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;


the chart shows [issues, PRs, discussions and commits](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/why-are-my-contributions-not-showing-up-on-my-profile) on GitHub





&lt;p&gt;I count myself incredibly fortunate to be able to make a living from being a &lt;a href="https://roe.dev/blog/funding" rel="noopener noreferrer"&gt;full-time open source maintainer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's something I &lt;em&gt;get&lt;/em&gt; to do rather than &lt;em&gt;have&lt;/em&gt; to.&lt;/p&gt;

&lt;p&gt;&lt;a href="/img/today-is-your-day/twitch-recap.png" class="article-body-image-wrapper"&gt;&lt;img src="/img/today-is-your-day/twitch-recap.png" alt="Twitch recap titled 'Grass-Toucher of the Year', with 839 new followers, 4.27K total hours watched, 118 new subscribers, 40 streams, 7.22K total chats sent, 8 clips and the Nuxt logo as the top channel emote"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's one reason I stream maintenance, building things or talking to people. You can find me on &lt;a href="https://tv.algora.io/danielroe" rel="noopener noreferrer"&gt;Algora&lt;/a&gt;, &lt;a href="https://www.twitch.tv/danielroe" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt; or &lt;a href="https://www.youtube.com/@danielroe" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;. I think of it as 'coding with friends' and it's part of the fun.&lt;/p&gt;

&lt;p&gt;If you've joined me on stream, sponsored me, contributed to Nuxt - or supported me in any of the many other ways people have made my life a joy this year, thank you ❤️&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next year, I want to continue to take joy in my work&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  There is fun to be done!
&lt;/h2&gt;

&lt;p&gt;In early 2023, arriving back from New Year holidays, I realised that I had really neglected my own health. On recommendation from &lt;a href="https://jess.sh/" rel="noopener noreferrer"&gt;Jessica Sachs&lt;/a&gt; and &lt;a href="https://marc.dev/" rel="noopener noreferrer"&gt;Marc Backes&lt;/a&gt;, I downloaded &lt;a href="https://www.noom.com/" rel="noopener noreferrer"&gt;Noom&lt;/a&gt;, dusted off my &lt;a href="https://ouraring.com/" rel="noopener noreferrer"&gt;Oura Ring&lt;/a&gt; and set off to look after myself a bit more.&lt;/p&gt;

&lt;p&gt;That year I lost 15 kg - and found my way back to good health. I also discovered some things that I loved doing - like &lt;em&gt;bouldering&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/reel/DBZJ9w0tWCR/" rel="noopener noreferrer"&gt;&lt;br&gt;
&lt;img src="/img/climbing.jpg" alt="Daniel climbing a route with pink holds in a bouldering gym"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a lovely, inclusive community, and if you ever fancy joining me for a climb (even as a total beginner!) you'd be very welcome.&lt;/p&gt;

&lt;p&gt;I've been bouldering just over a year (I started in September 2023), and in that time - mostly in 2024 - I've climbed in 35 gyms around the world. Blending physical fun and intellectual work has been a recipe for feeling like more of a whole person&lt;/p&gt;

&lt;p&gt;I can't attribute it just to bouldering, but over these last two years, I've begun to discover the importance of looking after my own needs. Rather than living entirely in my head, I think it's important to enjoy physicality and being 'embodied'.&lt;/p&gt;

&lt;p&gt;I don't entirely know what that will mean, but I want to continue to live in sync with what I need.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next year, I want to continue to look after myself&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  You’ll join the high fliers who soar to high heights
&lt;/h2&gt;

&lt;p&gt;I was tremendously honoured this year to &lt;a href="https://stars.github.com/profiles/danielroe/" rel="noopener noreferrer"&gt;join the ranks of GitHub Stars&lt;/a&gt;. I loved joining others at GitHub Universe and meeting folk in San Francisco - which absolutely lived up to its reputation!&lt;/p&gt;

&lt;p&gt;I was also mentioned by some of those filling out the State of JS 2024 survey. Thank you - it means a great deal. ❤️ &lt;/p&gt;

&lt;p&gt;&lt;a href="https://2024.stateofjs.com/en-US/resources/#people" rel="noopener noreferrer"&gt;&lt;br&gt;
&lt;img src="/img/today-is-your-day/state-of-js-people.png" alt="A list of influential developers for non-video channels, showing Daniel Roe in position 12"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next year, I don't want to stop learning and growing&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bang-ups and hang-ups can happen to you
&lt;/h2&gt;

&lt;p&gt;This year has brought it's own share of pain. I don't think that's unusual, but my own griefs are dear to me - at least because they are mine.&lt;/p&gt;

&lt;p&gt;I don't particularly want to write about them here, but for me it's important that I &lt;em&gt;really feel&lt;/em&gt; these things, not set them aside.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next year, I want to take time to feel the things that hurt, too&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  And YOU are the one who’ll decide where to go
&lt;/h2&gt;

&lt;p&gt;To finish with a few more words from &lt;a href="https://www.amazon.co.uk/PLACES-YOULL-GO_DR-SEUSS-illustrated/dp/0007413572" rel="noopener noreferrer"&gt;the poem&lt;/a&gt; that's inspired the title and headings of this post:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You have brains in your head. You have feet in your shoes. You can steer yourself any direction you choose.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm optimistic about the future. I don't know exactly what it will hold, of course - but let's surf the chaos together. Here's to another year of joy and love, friendship and fun! 🍻&lt;/p&gt;

</description>
      <category>newyear</category>
      <category>resolutions</category>
    </item>
    <item>
      <title>Using AI in open source</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Fri, 16 Aug 2024 20:04:38 +0000</pubDate>
      <link>https://dev.to/danielroe/using-ai-in-open-source-26n2</link>
      <guid>https://dev.to/danielroe/using-ai-in-open-source-26n2</guid>
      <description>&lt;p&gt;If you want to use AI to help you contribute to one of the projects I maintain, I would be delighted. But I have rules.&lt;/p&gt;

&lt;p&gt;Here's my take: Tech gives superpowers to people.&lt;/p&gt;

&lt;p&gt;For good or ill, technology is a force multiplier. It enables. Unlocks.&lt;/p&gt;

&lt;p&gt;And I'm thrilled that so-called 'AI' and the careful use of LLMs might empower people to contribute to open source and help them achieve amazing things.&lt;/p&gt;

&lt;p&gt;In fact, I'm experimenting with AI in some of the projects I maintain, using &lt;a href="https://maige.app/" rel="noopener noreferrer"&gt;maige&lt;/a&gt;, &lt;a href="https://dosu.dev/" rel="noopener noreferrer"&gt;dosu&lt;/a&gt; and more. I particularly like &lt;a href="https://copilot-workspace.githubnext.com/" rel="noopener noreferrer"&gt;Copilot Workspace&lt;/a&gt; - I think its approach is spot-on in creating code and docs in partnership with human direction.&lt;/p&gt;

&lt;p&gt;But I've also seen some (mostly unintentional) bad behaviour. So, on reflection, I think it's important to lay down two key ground rules:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Never let an LLM &lt;strong&gt;speak&lt;/strong&gt; for you
&lt;/h2&gt;

&lt;p&gt;If I read a comment or an email or an issue summary or a PR from you, I want to know that I'm hearing your words. I don't care about grammar or spelling - I won't think worse of you for that. I care more about real connection.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A note: AI-generated summaries of PRs are often &lt;em&gt;terrible&lt;/em&gt; and LLMs often optimise for long-winded, dense (and inaccurate!) text that is the opposite of what I would consider well-written. Simplicity is an art. The goal is not to sound impressive, but to communicate clearly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Never let an LLM &lt;strong&gt;think&lt;/strong&gt; for you
&lt;/h2&gt;

&lt;p&gt;Go ahead - drop the codebase in an LLM or get it to write the function or test you need. But the final step (and goal) before contributing that to an open source project should always be &lt;em&gt;understanding&lt;/em&gt; what it's written.&lt;/p&gt;

&lt;p&gt;Use computer aids to point you in the right direction, but always take personal responsibility. Saying, 'I'm not sure if this is helpful, but ChatGPT says ...' is always a cop out. I don't want to see quotes from an LLM in a PR or issue - I want to know what &lt;em&gt;you&lt;/em&gt; think.&lt;/p&gt;

&lt;p&gt;While I'm only speaking about open source contribution, I would commend these principles more generally.&lt;/p&gt;

&lt;p&gt;If this seems difficult, or feels like it might put you off contribution, please do let me know.&lt;/p&gt;

&lt;p&gt;And equally, if you have any ideas for using LLMs to empower contributors or maintainers in open source, I would love to hear them.&lt;/p&gt;

&lt;p&gt;I'm optimistic about the future.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Little oak</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Fri, 26 Apr 2024 15:41:44 +0000</pubDate>
      <link>https://dev.to/danielroe/little-oak-2p63</link>
      <guid>https://dev.to/danielroe/little-oak-2p63</guid>
      <description>&lt;p&gt;In the very centre of the forest, on the first day of spring, a little twig poked out of the ground.&lt;/p&gt;

&lt;p&gt;Every day he grew a little bigger.&lt;/p&gt;

&lt;p&gt;Every day new leaves unfurled.&lt;/p&gt;

&lt;p&gt;Before the end of the summer, he had two little branches, and he was very proud of himself.&lt;/p&gt;

&lt;p&gt;'Look at me!' he would shout out to his mummy. And Mother Oak would tell him he was perfect.&lt;/p&gt;

&lt;p&gt;In the autumn his leaves turned beautiful colours and then fell to the ground.&lt;/p&gt;

&lt;p&gt;And in the winter the snow fell in great drifts on the ground, and he could see the beautiful stars and the bright moon clearly through the branches of the bigger trees.&lt;/p&gt;

&lt;p&gt;The little oak tree was happy.&lt;/p&gt;

&lt;p&gt;And when the spring came again, even more leaves came poking out, and he started growing even more.&lt;/p&gt;

&lt;p&gt;Every day he grew a little bigger.&lt;/p&gt;

&lt;p&gt;But this year there was something new. By the end of the summer he had two little brown acorns with grey caps on his branches. He loved them so much.&lt;/p&gt;

&lt;p&gt;'Look at these!' he would shout out to his mummy. And Mother Oak would tell him the acorns were beautiful.&lt;/p&gt;

&lt;p&gt;But when autumn came and his leaves turned red and gold and orange, and all around him the forest was beautiful with colours, the little oak tree started to feel anxious.&lt;/p&gt;

&lt;p&gt;And when he started seeing the other trees dropping their acorns to the ground it got even worse.&lt;/p&gt;

&lt;p&gt;Every day he held on tighter and tighter to his little acorns.&lt;/p&gt;

&lt;p&gt;At night he was afraid they would fall to the ground.&lt;/p&gt;

&lt;p&gt;One day he was very upset, and Mother Oak asked him what the matter was.&lt;/p&gt;

&lt;p&gt;The little oak tree was still very small. He told his mummy why.&lt;/p&gt;

&lt;p&gt;'You don't need to worry,' she said reassuringly. 'If you let the acorns fall to the ground, then next year you will have even more.'&lt;/p&gt;

&lt;p&gt;And so the little oak tree let them fall, and the winter came, and then spring and summer.&lt;/p&gt;

&lt;p&gt;And the next year the little tree grew even bigger.&lt;/p&gt;

&lt;p&gt;And every year there were more acorns in his branches.&lt;/p&gt;

</description>
      <category>giving</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I'm funded</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Sun, 28 Jan 2024 21:57:29 +0000</pubDate>
      <link>https://dev.to/danielroe/how-im-funded-111e</link>
      <guid>https://dev.to/danielroe/how-im-funded-111e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Update&lt;/strong&gt;: this article was &lt;a href="https://github.com/danielroe/roe.dev/pull/1359" rel="noopener noreferrer"&gt;originally written in January 2024&lt;/a&gt; but has been updated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Being a full-time open source maintainer is a rare privilege. In the interests of transparency, let me explain a little more about how I am funded.&lt;/p&gt;

&lt;h2&gt;
  
  
  My story
&lt;/h2&gt;

&lt;p&gt;I had been increasingly involved in open source - and particularly in contributing to the &lt;a href="https://nuxt.com/" rel="noopener noreferrer"&gt;Nuxt&lt;/a&gt; ecosystem - whilst running first a creative agency and then a SaaS startup.&lt;/p&gt;

&lt;p&gt;But when I decided (with my co-founder) to shut down the startup, &lt;a href="https://atinux.com/" rel="noopener noreferrer"&gt;Sébastien Chopin&lt;/a&gt; asked if he could sponsor me to work on Nuxt. I was already committed to the core team - so it didn't take me long to accept.&lt;/p&gt;

&lt;p&gt;That enabled me to work on Nuxt full-time, and I was able to do so for several years, before &lt;a href="https://vercel.com/blog/nuxtlabs-joins-vercel" rel="noopener noreferrer"&gt;NuxtLabs was acquired by Vercel&lt;/a&gt; in July 2025.&lt;/p&gt;

&lt;p&gt;I also accepted a position at &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;, where I have the privilege of working full-time as the Nuxt project lead.&lt;/p&gt;

&lt;p&gt;I prize my independence highly and deeply appreciate the trust of Sébastien and the team at Vercel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sponsorship
&lt;/h2&gt;

&lt;p&gt;While I don't receive any direct funding from Nuxt via GitHub Sponsors, I do have &lt;a href="https://github.com/sponsors/danielroe" rel="noopener noreferrer"&gt;a number of individual and corporate sponsors&lt;/a&gt; that I value very highly.&lt;/p&gt;

&lt;p&gt;I see &lt;a href="https://roe.dev/blog/contributing-to-nuxt#what-open-source-is-to-me" rel="noopener noreferrer"&gt;open source as about 'mutual giving'&lt;/a&gt; and I appreciate these givers.&lt;/p&gt;

&lt;p&gt;Their kindness is deeply appreciated. I am looking for opportunities to thank my sponsors for their generosity, and would welcome ideas 🙏&lt;/p&gt;

&lt;h2&gt;
  
  
  Workshops and conferences
&lt;/h2&gt;

&lt;p&gt;I am sometimes asked to give paid-for workshops at conferences, and I have in past received a share of the revenue of these workshops.&lt;/p&gt;

&lt;p&gt;In addition, conferences cover the costs of my flights and hotel and (sometimes) a speaker's fee.&lt;/p&gt;

&lt;p&gt;If cost is ever a factor, &lt;strong&gt;please ask&lt;/strong&gt;. I do not charge for community events, nor do I speak at conferences for financial reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Streaming
&lt;/h2&gt;

&lt;p&gt;I receive some revenue from &lt;a href="https://www.twitch.tv/danielroe" rel="noopener noreferrer"&gt;streaming on Twitch&lt;/a&gt;. I do not enable ads or otherwise seek to monetise the streams.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>funding</category>
    </item>
    <item>
      <title>Using shared data when generating pages</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Mon, 15 Jan 2024 21:17:38 +0000</pubDate>
      <link>https://dev.to/danielroe/using-shared-data-when-generating-pages-45ok</link>
      <guid>https://dev.to/danielroe/using-shared-data-when-generating-pages-45ok</guid>
      <description>&lt;p&gt;You may have loved the shared 'payload' feature when generating Nuxt 2 apps. But did you know you can do the same in Nuxt 3?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use a shared 'payload'?
&lt;/h2&gt;

&lt;p&gt;First, what is a shared payload - and why would you want it?&lt;/p&gt;

&lt;p&gt;Rather than running the same code over and over again (for example, for every page of a blog that fetches some data from a CMS), you can perform the step once and share the data across all the generated pages.&lt;/p&gt;

&lt;p&gt;For example, if they are used on more than one page, you might want to extract and share data like a list of breadcrumbs, or a list of blog posts, or even the social links in the footer of your site.&lt;/p&gt;

&lt;p&gt;As the time taken to generate static pages slows down every deploy, if you &lt;em&gt;share&lt;/em&gt; this data across successive page prerendering, it can &lt;em&gt;significantly&lt;/em&gt; speed up the deployment process and decrease the number of hits on your content management system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using a shared payload in Nuxt 2
&lt;/h2&gt;

&lt;p&gt;In Nuxt 2, shared payload support was built in. You could use a shared payload as simply as this (&lt;a href="https://v2.nuxt.com/docs/configuration-glossary/configuration-generate/#speeding-up-dynamic-route-generation-with-payload" rel="noopener noreferrer"&gt;see Nuxt 2 documentation&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;~/nuxt.config.ts&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="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;routes&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="nx"&gt;axios&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;https://my-api/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&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;return&lt;/span&gt; &lt;span class="nx"&gt;res&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;payload&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="p"&gt;})&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This 'payload' then becomes part of the Nuxt context, accessible (for example) in your data fetching hooks:&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;asyncData &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using a shared payload in Nuxt 3
&lt;/h2&gt;

&lt;p&gt;When we released Nuxt 3, we didn't document a successor to this shared payload functionality in Nuxt 2.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Note&lt;/strong&gt; that we also use the word 'payload' to refer to everything we transfer from the server to the client in Nuxt 3, so I've tried to use 'shared payload' consistently here - but be aware that if you're reading old articles it might be confusing.&lt;/p&gt;

&lt;p&gt;We didn't directly port this feature across to Nuxt 3 for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;We want the &lt;code&gt;nuxt.config&lt;/code&gt; to be fully serialisable&lt;/strong&gt;. Ideally it shouldn't contain much (if any) code that couldn't fit in a normal JSON object. (And &lt;em&gt;zero&lt;/em&gt; runtime code.) That has already unlocked future capabilities for us including the ability to have an entirely self-contained &lt;code&gt;.output/&lt;/code&gt; folder for Nuxt builds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;More significantly, &lt;strong&gt;we already support a much more powerful &lt;em&gt;storage&lt;/em&gt; layer&lt;/strong&gt;. It's possible with a very few steps to duplicate this functionality in a much more granular and customised way, with &lt;a href="https://nitro.unjs.io/guide/storage" rel="noopener noreferrer"&gt;the shared storage layer we've built into Nitro&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before I share an example of how you might do that yourself, I should say that there's a module to make this much easier: &lt;a href="https://nuxt-prepare.byjohann.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;nuxt-prepare&lt;/strong&gt;&lt;/a&gt; by Johann Schopplich. Check it out!&lt;/p&gt;

&lt;p&gt;But if you wanted to build this yourself, here's how you might do it. This approach uses Nitro's storage layer to store data between prerendered routes, running in a Nitro server plugin:&lt;/p&gt;

&lt;p&gt;~/server/plugins/payload.ts&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPayload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dedupe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payload&lt;/span&gt;&lt;span class="dl"&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="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;$fetch&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://jsonplaceholder.typicode.com/todos&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineNitroPlugin&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;nitroApp&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="c1"&gt;// expose payload to each request if we are prerendering&lt;/span&gt;
  &lt;span class="nx"&gt;nitroApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;event&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prerender&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getPayload&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="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// avoid duplicating calls in parallel as prerender process&lt;/span&gt;
&lt;span class="c1"&gt;// calls a number of renders at the same time, before the&lt;/span&gt;
&lt;span class="c1"&gt;//  first payload is initialised&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dedupe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;fn&lt;/span&gt;&lt;span class="p"&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;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="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="nf"&gt;fn&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;// cache result in memory by default - though&lt;/span&gt;
&lt;span class="c1"&gt;// we could also cache it in data store:&lt;/span&gt;
&lt;span class="c1"&gt;// 👉 https://github.com/unjs/nitro/pull/1352&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;key&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="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&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;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;getItem&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;value&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;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&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;You could then use this shared payload in a Vue component (or Nuxt plugin) like this:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRequestEvent&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;useAsyncData&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="k"&gt;if &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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prerender&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;$fetch&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://jsonplaceholder.typicode.com/todos&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;This approach uses &lt;code&gt;import.meta.prerender&lt;/code&gt;, which allows us to &lt;em&gt;tree-shake&lt;/em&gt; code out of our builds so you only include this payload code in your app when you are prerendering your app. (In the example above it's quite minimal, but it's worth being aware of in your own projects to optimise your bundle size.)&lt;/p&gt;

&lt;p&gt;You can check out this &lt;a href="https://stackblitz.com/edit/nuxt-shared-payload?file=server/plugins/payload.ts" rel="noopener noreferrer"&gt;full StackBlitz example&lt;/a&gt; - make sure to run &lt;code&gt;pnpm generate&lt;/code&gt; to confirm that the console log only runs when the first page is prerendered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Payload extraction
&lt;/h2&gt;

&lt;p&gt;It gets even better. Nuxt turns on something called 'payload extraction' when you prerender your pages. (You can also turn it on manually even when you have a runtime server, with the &lt;code&gt;experimental.payloadExtraction&lt;/code&gt; option.) &lt;/p&gt;

&lt;p&gt;Without payload extraction, your data fetching composables (&lt;code&gt;useFetch&lt;/code&gt; and &lt;code&gt;useAsyncData&lt;/code&gt;) will rerun on &lt;em&gt;client-side&lt;/em&gt; navigation. But &lt;em&gt;with&lt;/em&gt; it, this data is extracted into a &lt;code&gt;payload.json&lt;/code&gt; file which can be used instead of rerunning the composables.&lt;/p&gt;

&lt;p&gt;If you are prerendering every route of your app, you can therefore confidently early return or throw an error which means your data fetching code can also be tree shaken out from your final app. (That's what I do in my website: &lt;a href="https://github.com/danielroe/roe.dev/blob/main/src/components/TheTalks.server.vue#L37-L38" rel="noopener noreferrer"&gt;see here&lt;/a&gt; for example.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps for prerendering optimisations
&lt;/h2&gt;

&lt;p&gt;👉 In addition to &lt;strong&gt;nuxt-prepare&lt;/strong&gt;, we're already talking about how to make this easier for users (and automatic!). Follow &lt;a href="https://github.com/nuxt/nuxt/pull/24894" rel="noopener noreferrer"&gt;pull request #24894&lt;/a&gt; for our thoughts and implementation.&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>generate</category>
    </item>
    <item>
      <title>Governance and abuse</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Thu, 27 Jul 2023 16:10:36 +0000</pubDate>
      <link>https://dev.to/danielroe/governance-and-abuse-485d</link>
      <guid>https://dev.to/danielroe/governance-and-abuse-485d</guid>
      <description>&lt;p&gt;Whenever you have people working together, there's potential for great things. There's also potential for harm - and sadly that's something we need to think about too.&lt;/p&gt;

&lt;p&gt;I'm not writing this in response to a problem, but because I believe two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Nuxt community should be &lt;em&gt;safe for you&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;If there's a problem, &lt;em&gt;something should be done about it&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Nuxt governance
&lt;/h2&gt;

&lt;p&gt;Before starting as framework lead, I worked on both &lt;a href="https://github.com/nuxt/governance" rel="noopener noreferrer"&gt;governance documents&lt;/a&gt; and put a &lt;a href="https://github.com/nuxt/.github/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;code of conduct&lt;/a&gt; in place.&lt;/p&gt;

&lt;p&gt;I think the most important line in our governance document - one I care about being there - is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The project lead is selected by the authors and can at any point be changed if there are issues with their leadership.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means I lead Nuxt, but only by agreement.&lt;/p&gt;

&lt;p&gt;So if you ever have an issue with someone within Nuxt, even me, there is always a way to report and handle it that does not involve that person.&lt;/p&gt;

&lt;p&gt;Here are some thoughts about why I think that is particularly important in open source - and a request. 🙏&lt;/p&gt;

&lt;h2&gt;
  
  
  A community of choice
&lt;/h2&gt;

&lt;p&gt;First, an open source community is made up of people who &lt;strong&gt;choose&lt;/strong&gt; to be part of it. I &lt;em&gt;love&lt;/em&gt; that. I think this freedom of choice unlocks some wonderful things that we should rightly aspire to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No barrier to entry&lt;/strong&gt;. No interview to start. No necessary privileged background. No special career path. You are welcome here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No power games&lt;/strong&gt;. Do what inspires you, not what you &lt;em&gt;have&lt;/em&gt; to do. Contribution to open source should not be a millstone around your neck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared vision&lt;/strong&gt;. Because we're all here by choice, to some degree we share a vision. That makes it possible to have real team spirit to forge genuine relationships around a common goal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it also brings some potential dangers when things go wrong:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If toxic behaviour becomes part of the ecosystem, &lt;strong&gt;people may choose to leave quietly&lt;/strong&gt;. That makes it very possible for a maintainer not to know that there is an issue until far, far too late. It's even worse if a team member is the one causing issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are &lt;strong&gt;fewer ways to enforce good behaviour&lt;/strong&gt;. It's not a job. There's no HR department or contract with consequences if things go wrong.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Because it isn't just 'work', when things go wrong &lt;strong&gt;people can be affected even more deeply&lt;/strong&gt;. Any toxic behaviour is bad, but somehow it feels more destructive when it appears inside a hobby - something that was life-giving.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So we need to be active in establishing what acceptable behaviour is - and listening out for anything that indicates we have a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  An appeal
&lt;/h2&gt;

&lt;p&gt;As I said, I'm not writing this because of a problem with the Nuxt community. But neither is it a purely theoretical question. Because we're a community of people, we can get it wrong - and what matters is how we deal with that.&lt;/p&gt;

&lt;p&gt;👉 So here's my appeal. If you encounter &lt;strong&gt;any toxic, abusive, or unkind behaviour&lt;/strong&gt; within the Nuxt ecosystem, please let us know, even anonymously. Especially if that person is me or on the team.&lt;/p&gt;

&lt;p&gt;You can contact &lt;a href="https://github.com/nuxt/.github/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;any person listed in our code of conduct&lt;/a&gt; via their personal email address. They will investigate appropriately and keep your identity confidential (if permitted by law).&lt;/p&gt;

&lt;p&gt;I would be very grateful.&lt;/p&gt;

&lt;p&gt;❤️&lt;/p&gt;

</description>
      <category>governance</category>
      <category>opensource</category>
    </item>
    <item>
      <title>A guide to Nuxt server components</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Mon, 24 Jul 2023 20:56:33 +0000</pubDate>
      <link>https://dev.to/danielroe/a-guide-to-nuxt-server-components-4me9</link>
      <guid>https://dev.to/danielroe/a-guide-to-nuxt-server-components-4me9</guid>
      <description>&lt;p&gt;'Server components' are becoming increasingly common in the web development ecosystem, for good reason.&lt;/p&gt;

&lt;p&gt;Traditionally, in a single-page application, even a server-rendered one, the server is only relevant for the &lt;em&gt;first&lt;/em&gt; load, after which the client takes over. That has meant that &lt;em&gt;every&lt;/em&gt; part of a web app must be capable of being rendered on both client and server. Alternatively, people have opted for multi-page apps, or MPAs, with the cost this brings in user experience.&lt;/p&gt;

&lt;p&gt;But this is not always desirable.&lt;/p&gt;

&lt;p&gt;Instead, server components allow server-rendering individual components within your client-side apps.&lt;/p&gt;

&lt;p&gt;It's possible to use server components within &lt;a href="https://nuxt.com/" rel="noopener noreferrer"&gt;Nuxt&lt;/a&gt;, even if you are generating a static site. That makes it possible to build complex sites that mix dynamic components, server-rendered HTML and even static chunks of markup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key benefits
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;⚡️ Server components allow you to extract logic &lt;strong&gt;out of your client-side bundle&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br&gt;By moving code into server components, these components (and the components &lt;em&gt;they&lt;/em&gt; use) no longer need to by hydrated or 'tracked' by Vue. This is particularly useful for complex or expensive operations that probably don't need to be 'rerun' on the client, like applying a syntax highlighter or parsing markdown.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;In most cases, using server components in your Nuxt site won't be a magic bullet. Rather, it will be a useful option when there is an disproportionate amount of code needed to render a component on the client.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🔐 Server components ensure that &lt;strong&gt;privileged code runs securely&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br&gt;When your logic requires access to a database or needs a private key or secret, server components can be a useful solution. They are one way of separating your concerns. (Though note that other &lt;strong&gt;good&lt;/strong&gt; alternatives exist, like moving your server-only code into a Nitro server route that is 'fetched' by your component.)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;📦 Server components &lt;strong&gt;don't necessarily require a server at runtime&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br&gt;By default, Nuxt will prerender any server components used in your application. As long as you've crawled every page of your site, and don't load them only on the client, or change the props at runtime, server components should work just as well on a fully static website.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;This means you can use server components on &lt;strong&gt;static hosting&lt;/strong&gt; - no need to update to serverless/edge rendering in order to benefit.&lt;/p&gt;


&lt;blockquote&gt;⚡️ Plus, if you have enabled payload extraction (which is enabled by default in generated/static sites, and can also be enabled for hybrid deployments), then Nuxt will even prefetch server components used in pages you might navigate to, so they will load instantly.&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;🔄 Server components &lt;strong&gt;are interchangeable with normal components&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br&gt;Server components/islands can support all the features of normal components, including shared state, access to the current route, and more. Because they behave just like normal components, you can nest them within server components or just sprinkle them through the rest of your code.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;By default, all your plugins will run when rendering server components, unless (coming soon) they are explicitly disabled by setting &lt;code&gt;island: false&lt;/code&gt; when defining your component.&lt;/p&gt;
&lt;h2&gt;
  
  
  Similar but different
&lt;/h2&gt;

&lt;p&gt;There are a other similar-sounding terms floating around that are worth mentioning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React server components (or RSCs)&lt;/strong&gt;. This is an entirely different approach to rendering server components which is often linked to streaming responses from server to client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;'Island' architecture&lt;/strong&gt;: named by &lt;a href="https://sylormiller.com/" rel="noopener noreferrer"&gt;Katie Sylor-Miller&lt;/a&gt; and popularised most recently by frameworks like &lt;a href="https://iles.pages.dev/" rel="noopener noreferrer"&gt;îles&lt;/a&gt; or &lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;Astro&lt;/a&gt;, this is an architecture which embeds dynamic 'islands' within more static surroundings. The Nuxt approach is the opposite - we embed static 'islands' within a dynamic Nuxt app.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Using server components
&lt;/h2&gt;

&lt;p&gt;So, how do you use a server component?&lt;/p&gt;

&lt;p&gt;First, you'll need to enable the feature (which is still experimental):&lt;/p&gt;

~/nuxt.config.ts


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;experimental&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;componentIslands&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;Then you can 'convert' a component to a server component simply by adding a &lt;code&gt;.server.vue&lt;/code&gt; suffix. For example, here's a version of my site footer:&lt;/p&gt;

~/components/the-site-footer.server.vue


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;links&lt;/span&gt; &lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GitHub&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i-ri:github-fill&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;link&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://github.com/danielroe/&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="c1"&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;year&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;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&lt;/span&gt; &lt;span class="ni"&gt;&amp;amp;copy;&lt;/span&gt; 2019-&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; Daniel Roe. &lt;span class="nt"&gt;&amp;lt;/small&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ link, name, icon } in links"&amp;gt;
          &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;:href=&lt;/span&gt;&lt;span class="s"&gt;"link"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-4 w-4 fill-current"&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"icon"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;There's no need for any of that to be dynamic, so this is a great candidate for a server component. All I did was add the &lt;code&gt;.server.&lt;/code&gt; suffix. I still use it in exactly the same way as before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LayoutTheSiteHeader&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NuxtPage&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LayoutTheSiteFooter&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Case study: Nuxt Content
&lt;/h3&gt;

&lt;p&gt;One interesting use-case is to create a server component that simply renders a Nuxt content page. Assuming you have &lt;code&gt;@nuxt/content&lt;/code&gt; installed, this magical component will render any route as a server component.&lt;/p&gt;

&lt;p&gt;~/components/static-markdown-render.server.vue&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;ContentRendererMarkdown&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;#components&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dev&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;useAsyncData&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;queryContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;findOne&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;gt;&lt;/span&gt; &lt;span class="nf"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContentRendererMarkdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&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;value&lt;/span&gt;&lt;span class="o"&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;value&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;queryContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;findOne&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;gt;&lt;/span&gt; &lt;span class="nf"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContentRendererMarkdown&lt;/span&gt;&lt;span class="p"&gt;,&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="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;I then use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;StaticMarkdownRender&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ For now, &lt;code&gt;&amp;lt;NuxtLink&amp;gt;&lt;/code&gt; components are not interactive, meaning you might need to add some code like this in the parent page, as a 'pretend' version of client-side routing:&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;parseURL&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;ufo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleNavigationClicks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MouseEvent&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&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;anchor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anchor&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;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;host&lt;/span&gt; &lt;span class="o"&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;host&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;roe.dev&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;navigateTo&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;pathname&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="nf"&gt;navigateTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;external&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;p&gt;I plan to keep this article up-to-date as we roll out new features and update how this works. If you have any questions, please &lt;a href="mailto:daniel@roe.dev"&gt;let me know&lt;/a&gt; and I'll do my best to cover them here.&lt;/p&gt;

&lt;p&gt;If you're interested in following on, here are a few next steps I'm pretty excited about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🌎 &lt;strong&gt;Remote sources&lt;/strong&gt;. It will be possible soon to load server components from other websites, enabling you to create Nuxt microservices that render components which you can use in different websites. &lt;a href="https://github.com/nuxt/nuxt/pull/21592" rel="noopener noreferrer"&gt;Check out this PR&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;😴 &lt;strong&gt;'Lazy' server components&lt;/strong&gt;. Soon it will be possible to display 'fallback' content while a server component loads to avoid blocking navigation. &lt;a href="https://github.com/nuxt/nuxt/pull/21918" rel="noopener noreferrer"&gt;Check out this PR&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🏝️ &lt;strong&gt;Islands of interactivity&lt;/strong&gt;. It's already possible to have interactive client slots within server components, but soon we will support arbitrary interactive components within server component HTML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;💡 &lt;strong&gt;ServerOnly&lt;/strong&gt;. It might be nice to support a &lt;code&gt;&amp;lt;ServerOnly&amp;gt;&lt;/code&gt; component that automatically converts sections of markup into server-only sections that get rendered on the server...&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also follow the &lt;a href="https://github.com/nuxt/nuxt/issues/19772" rel="noopener noreferrer"&gt;Nuxt server component roadmap&lt;/a&gt; in our GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring futher
&lt;/h2&gt;

&lt;p&gt;If you want to see which parts of my site are server components, try clicking this button to see what I've chosen to render as a server component - and then click around to other pages:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;/span&gt; Show server component outlines&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>servercomponents</category>
    </item>
    <item>
      <title>An open invitation</title>
      <dc:creator>Daniel Roe</dc:creator>
      <pubDate>Sat, 24 Jun 2023 21:12:08 +0000</pubDate>
      <link>https://dev.to/danielroe/an-open-invitation-64b</link>
      <guid>https://dev.to/danielroe/an-open-invitation-64b</guid>
      <description>&lt;p&gt;A few months ago I tweeted out an open invitation for anyone new to contributing to open source.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're new to contributing to open source or &lt;a href="https://twitter.com/nuxt_js" rel="noopener noreferrer"&gt;@nuxt_js&lt;/a&gt;, and want to, let me know. I'd be really happy to have an informal chat, pre-PR review, etc. ❤️&lt;/p&gt;

&lt;p&gt;— &lt;a href="https://twitter.com/danielcroe/status/1630239320375463937" rel="noopener noreferrer"&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When people messaged me, I sent through a link so they could book a short call at a time that worked for them.&lt;/p&gt;

&lt;p&gt;I was honestly astounded at how many people wanted to chat. People I had never met or encountered. And even people I 'knew' from online. Some wanted to contribute but were entirely new to open source. Some had ideas they wanted the chance to implement. A couple wanted me to 'pitch' Nuxt to them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I had mixed feelings that &lt;em&gt;so many&lt;/em&gt; people wanted to talk - at first. Seeing virtually every free day I had be booked for the next month was a little daunting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Looking back at those calls, I don't regret a single one. A number of people I'd now consider valuable contributors to Nuxt messaged me - and we had a chance to talk for the first time. And I think there were plenty of folk who would be assets to any project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I've summarised &lt;a href="https://roe.dev/blog/contributing-to-nuxt" rel="noopener noreferrer"&gt;a few thoughts&lt;/a&gt; about contributing to Nuxt that came out of these calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I absolutely want to have an open-door policy in future.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  An open invitation
&lt;/h2&gt;

&lt;p&gt;So here's the deal. If you want to have a 10-minute chat about anything, then I would love to talk to you.&lt;/p&gt;

&lt;p&gt;Particularly, if you want to be involved in open source and you feel you lack &lt;em&gt;experience&lt;/em&gt; or &lt;em&gt;background&lt;/em&gt;, please let me know. I will make time for you and I know others will too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cal.com/danielroe/intro" rel="noopener noreferrer"&gt;https://cal.com/danielroe/intro&lt;/a&gt;&lt;/p&gt;

</description>
      <category>communication</category>
      <category>contact</category>
    </item>
  </channel>
</rss>
