glad you find it interesting! the plan is to support more frameworks/langs moving forward. The poly-frontend option might be even fairly easier to introduce since Wasp is doing more stuff closer to the server.
Hype driven developers/marketers believe the only type of websites that exists are those which need indexable content for SEO purposes. More news at 11
That should be true though, if it doesn’t have indexable content whose URL could theoretically be permanent, it shouldn’t be crammed into a web page. Write an application instead.
I think to sway the only benefit of Next.js is DEO is underselling how useful it is.
Sure SEO is important for most people anyway, but having multiple pages that load instantly rather than having to wait for a server call is also pretty handy. Plus auth working better.
I don’t see why next wouldn’t be the default and react now the outlier.
Agreed, this is how our team uses it. We hire React devs and teach them Next.js day 1 and essentially their React experience is helpful but Next is the main focus for the devs.
As far as I understand you can use these frameworks to write SPAs as well. I have no idea how well supported that use case is in the end.
I find the idea that you want to handle data fetching and routing in a framework to be reasonably convincing. There are advantages here, and it's easy to get into a bit of a mess if you just fetch data in each component.
The part that has stopped me from looking at the frameworks until now is that they add a lot of parts I don't need, and the documentation seems to be focused on the SSR part. And then there are React server side components, which is another new concept I need to understand. Maybe the frameworks are a good fit for my SPA use cases, but it'll take quite a bit of time to find out if that is true.
Basically if you do a static export from next.js and ignore routing, you get a react SPA.
You can do the same in Gatsby, but it's probably a waste of time.
But...
With an index.html file containing a createRoot(document.getElementById('root')).render(<MyApp/>) call, and parcel or vite or webpack, you can produce much the same thing.
Possible that next.js will give you easier access to some more interesting ways to split your JS bundle up - but also possible it will fight you if you continue to insist on not taking advantage of SSR.
If you roll your own with a bundler, you will also need to integrate a router. Next.js is providing a routing layer for you. If you want to stick with a static/SPA the entire time, that's fine. You don't have to use SSR unless you need it.
I don't think that's a fair characterization of the "Start a New React Project" page [0]. Next.js is the first option listed and is described as a way to "create React apps of any size—from a mostly static blog to a complex dynamic application."
This reads to me like "Next.js can do SPAs (like CRA) plus static sites and SSR". Next.js' site even says "The core of Next.js has been designed to enable starting as a static site (or Single-Page Application)" [1].
Your understanding is correct – Next.js can do static sites, SPAs, SSR – all of them.
We (just today) updated the Next.js docs linked based on feedback around this to make it more clear. Hopefully this helps, let me know if you have other feedback.
"The core of Next.js has been designed to enable starting as a static site" is a little contradicted by the fact static export is considered an 'advanced feature' though.
That said, I'm not sure why running `next export` is considered 'advanced'.
I'd say this is documentation organization "debt" – there's a bunch of "advanced" features that aren't that advanced. We're aware and fixing with the new docs -> https://beta.nextjs.org/
This is what has made me hesitant to really invest deeply in Next.js. It's just too familiar where some open source project starts. Later it attempts to monetize. Some feature in open source makes it so new monetization thing (usually cloud functionality) isn't needed, so those feature(s) get downplayed, neglected, and eventually deprecated, often with self-fulfilled prophecy/declaration of "nobody is using those" (because they were engineered that way, but that inconvenient part is never mentioned and rarely acknowledged). It's one thing not to invest in unprofitable features (that's understandable for a for-profit company), but making them difficult or more obscure to use is often a part of this pattern.
I'm not saying Next.js is doing that with static export, but I'm not sure they aren't either. It fits the pattern too well. I'm still suspicious about how the Image implementation (which nearly every website needs) breaks `export` and the only solution is "roll your own image handler." I'm not sure if that fits into the understandable lack off investment or the intentional difficult/obscure.
We've made quite a few improvements to the static export with the new App Router, including support Server Components, Route Handlers, i18n routes, and more. Definitely still being invested in. My comment about documentation debt is that the entire information architecture of the Next.js docs needed some work. It's being fixed and will be stable soon.
You can read more about how to use Image Optimization with a static export in the new docs: https://beta.nextjs.org/docs/configuring/static-export. There's a full example there with Cloudinary, but you could use any service you want.
Nice, thanks for the link. Those new docs do look great!
I wanted to note that I'm not asking you to build this, I'm more sharing my use-case in case it's helpful feedback.
What would really be amazing for me is a build-time image processing pipeline. Any images I use for the static site are already present in the repo (none are user-supplied or come from object storage, etc). Since all the image info is present at build/export time, it would be amazing if the image processing were done locally during the build and then the next/Image tags would instead of invoking server-side code, generate the static <img> code necessary to reference the different versions (such as srcset, sizes, etc)[1]. There is at least one open source project to do that, but at least when I last tried it, it was essentially dead on the vine. I searched around but couldn't find any solutions, which was pretty disappointing. I did end up shipping the app and just manually pipelined those images and hacked out the <img> tags instead of using the component, but if I had more than a handful in the site that wouldn't scale too well.
Anyway, thanks for what you've done with next.js! it's really an incredible project and you've been an important part of moving the web forward.
Vercel's next.js and sveltekit are both SSR first because that's its business needs, which has nothing to do with mine(CSR only case), and Vercel is actively pushing the SSR-can-do-it-all in the open source space, I feel it is very much short-sighted.
Just use vuejs which is the only one truly never forces SSR on you if you do not want to have anything to do with it.
I actually strongly advocate for: SSR and server is the absolute best default[1], and Next.js gives you tremendous flexibility on where to place your compute[2], including skipping SSR altogether[3], with the best-in-class static export that can actually at least put some content in your HTML instead of a blank page[4]
Speaking as an engineering manager, vercel’s approach seems to cater to the last market where overengineering and complexity were status symbols that middle management was happy to pay for. When the headcount was free, there weren’t many questions from upper management why basic UIs required so much heavy lifting by (overly) experienced engineers.
In the new market, there will be much more scrutiny on costs and the complexity that creates it. The prospect of hiring a “React Engineer” with 7+ years of experience to build a cookie cutter UI, will be just as questionable as forcing the front end and backend to use the same technology and framework governed by one single vendor.
Interestingly, I have the exact opposite bet: “SPAs were a zero interest rate phenomenon”. Putting the burden of compute on clients, and shipping slower apps for the sake of DX and convenience. Customer-first wins.
SPAs are faster than SSR because you can choose whether to incur network latency or not.
For example, let’s consider a site with two pages. In the SSR case, if I click the link to page 2, then I have to wait a whole network roundtrip for the page to appear.
In the SPA case you can decide when you want to load the content for page 2: with page 1 (if it’s a small amount of content), if the user scrolls to a certain point, … it’s completely up to you. You can cleverly hide the latency so that when the user does navigate to page 2, it’s instant.
MPAs can do the same trick. Use JavaScript to add a <link rel=prefetch> element to prefetch a URL. Or just serve your server-side rendered page with this element included to prefetch the next page. When the user navigates to the next page, it’s instantly shown.
You can do what you described with Next.js and latest React easily.
In addition, it will also help with SSR where it makes sense for speed and performance.
Building site with Next.js makes it simple to get a good perceived performance, the framework handles it out of the box.
Vercel is I think going to have a great time of it. Setting up code pipelines, and the devops time needed for it, compared to just having it deploy from github, and having sane logging?
Only people who haven't had to set all this up themselves think Vercel isn't amazing.
It is handling a LOT of devops heavy lifting for you.
next export, the feature that produces a "true" SPA out of a Next.js app, has been under-developed for along time. However the very newest developments in Next 13 seems to fix that, making Next.js truly versatile
Starting a "new react project" should be basically creating an HTML file, and adding a script tag linking to React the JS library. Why are these developers always trying to obfuscate everything with tons and tons of layers of indirection all the time? You don't need to "bundle" anything and certainly not use some server just to add Javascript to a page (unless it's a matter of CSP of course) and you should certainly not have to rely on nodejs or cli tool X,Y,Z...
Somehow the JS/Node dev community managed to re-invent JEE web profile, and is very close to re-invent Glassfish as well at that point, but worse because it didn't learn anything from Java enterprise... this madness needs to stop.
I honestly find this way more intuitive than JEE profiles.
It just makes sense when you take react as what it is: a library. Now, if you want amenities like a router you need to build it yourself or use something existing. 99.9% of people want this, so why not point them into the right direction?
Because it's slow. Hard to do treeshaking if everything is in random dependencies that need to be downloaded at runtime. You also get a flash of white if you don't pre-render your sites.
You can actually still do this, and it is kind of a shame it's not documented on react.dev
You need to pull in react, plus Babel standalone, and then you can use <script type="text/jsx"> tags, which means you can bootstrap react components onto your page. But you are going to be basically running a compiler in your user's web browser. That's fine if you want to run that way, but Babel has docs that explain why you probably shouldn't (https://babeljs.io/docs/babel-standalone#when-not-to-use-bab...).
Building up my initial knowledge like you describe was the only way I could generate the enthusiasm for working on top of so many layers of abstraction.
I just want to say, as a developer that just wants to get stuff done, I'm so annoyed by frameworks needing a meta framework, etc, etc. I want something as simple as CRA to be enough.
There are a myriad of reasons why I prefer SPA to server rendered content for most applications. The main exception is if I have a public facing, unauthenticated application that I need indexed, I'll go for SSR.
Off the top of my head, here are benefits to SPA:
- I can just serve a few static files from a CDN. Every user gets the same client.
- Most requests made by the application are actually smaller. I'm just loading the data I need, rather than the data, markup and styling.
- It's an actual client application talking to a data API. It's the same API the rest of my client applications are talking to, be it a mobile API, native, CLI, etc.
- It's a much easier mental model. Interactivity without having to give consideration to whether or not it will disrupt whether it can be rendered. I build my application like a realtime application and just make requests for the data I need when I need it
- I don't have to think about exposing backend secrets, or trying to do things I'm mistakenly assuming to necessarily run in one environment or the other
- I can be much more explicit about loading and caching data when I would like to
Even most of the cons of a SPA can be ameliorated. The biggest con is a larger up front load, but that can be mitigated by code splitting and lazy loading. The fact that it's a handful of static files means that the application is basically cached, too. And SPAs are for applications, not websites. Most people using SPAs want the application experience to be optimal, not necessarily their initial first time load. They want small requests, interactivity, live feedback. This is all possible with SSR, but nowhere near as simple.
You get all these benefits using something like NextJS's static site exports which I'm using right now on Cloudflare Pages (it's built-in). Works perfect for a SPA plus you get the SEO benefits. Only downside is we had to use query param for URLs instead of path-based params but it works the same in the code
React frameworks are mostly hype in order to justify using a particular PaaS. They’ve hired all the influencers and using it to their advantage.
There definitely are good reasons to use SSR and these frameworks, but a fully interactive web app that acts like a desktop app isn’t one of them.
All of that to say I have no issues with it and react is still awesome. It’s a view _library_ and works great for its relatively restrained API. Most of the new features are opt-in and I don’t really touch them (besides hooks).
Totally agree! Plus if you use PWA, you get some benefits of an installable apps (not on all platforms though) but the support is alright on iOS too (more features are supported than before)
I built a small demo app with 3 views (each loading lazily when first requested or loading in background using service worker) with view transitions, back button and scroll position retention. (built for mobile devices but works on desktops too) https://stage-starter.netlify.app
I don't understand the pivot back to SSR. Tearing down and standing up the entire DOM and page memory between navigations is just unnecessary work. Little things like maintaining scroll position in the page's navigation bar meaningfully improve usability and are only achievable with a SPA-based approach. This doesn't discount the challenges of building SPAs: bundle sizes, performance, etc. can be concerns if not managed. That's true of any application.
the biggest problem with SPAs is none of the devs making them seem to remember how nice it was to open different pages of a site in different tabs. it's all horribly phone/tablet centric. middle-clicking doesn't even pop links in new tabs because they break basic browser features. you're lucky if you can even tell what's a real link and what's just going to rearrange your current page.
And even big sites built by well paid engineers that should know better (I’m looking at you Microsoft Azure!) have these issues! Sometimes middle click works. Sometimes it doesn’t. Sometimes right click open in new tab works. It’s so damned annoying.
This often has little or nothing to do with SPAs though. Quoted tweets on Twitter on twitter.com, for example, can’t be right- or middle-clicked for…absolutely no good reason. They just don’t render an <a>. Yet twitter.com is an SPA, and the little “30m” time indicator on a tweet is a fully working <a> that can be right- and middle-clicked and also does a client navigation when clicked normally.
Find in Page is another common casualty, and frustratingly it’s not always re-implemented by the SPA.
I think a lot of the ire against SPAs and other flavors of JS heavy pages would dissipate if devs made a point of trying to not unnecessarily break browser features and when breakage is unavoidable, furnishing replacements for the broken features that are as good as or better than the originals.
I don't understand this. All the popular/used routing frameworks by default support "open link in new tab" (render <a href="..." />, and listen to onClick to do SPA transition). Developer have to deviate from the easy and commonly documented way of doing things to break this. Any website that doesn't do this is fundamentally broken and built by teams that deliberately disregarded this behaviour.
I don't know which sites use what particular frameworks and paradigms (and I don't recall offhand which sites I've had these problems with), but I frequently have problems with sites that will, when I command-click on a link (standard shortcut to open in new tab on Mac), either open the page in the new tab and change the current tab to it, or just completely ignore my expressed desire and only change the current tab.
"But all the frameworks support doing the good thing! But only people who are bad at it make bad UX!"—well, it's still happening. No amount of contempt for the people doing it changes that.
This only happens now with an SPA due to laughable incompetence or deliberate disregard. You have to go out of your way to not use whatever Link component or similar tool provided by your SPA library/framework of choice. Any team that incompetent or negligent would be just as likely to break link behavior even if they aren’t using an SPA.
I’m surprised the criticism is still ubiquitous: it’s either 5+ years out of date or some people run into these terrible sites a lot for some reason.
These criticisms are still ubiquitous because these sites are still ubiquitous.
For example, less than 2 years ago someone did a "Show HN" of a Shopify front end they launched for their wife that was literally almost entirely nonfunctional. Not exaggerating.
Has that page changed a lot since then? Every link out of a dozen or so that I quickly checked were all real <a> tags that worked fine with middle- and right-clicking. I couldn't reproduce the back button behavior in your complaint either.
> Little things like maintaining scroll position in the page's navigation bar […] are only achievable with a SPA-based approach.
That’s not true. I wrote non-SPA web applications in the mid-aughts that maintained scroll position throughout server roundtrips, using JavaScript and storing the current scroll position in hidden fields upon submit. Even multiple scroll positions for nested panes. It also adjusted the saved scroll positions correctly when new elements were added to or removed from the page during the server roundtrip. This was encapsulated in a server-side HTML rendering framework.
Er, lots apparently. Just now I was searching through posts on a Facebook event to find more details. I thought I finally found what I was looking for buried a few months deep and clicked it. It was the wrong item so I clicked back and Facebook scrolled me to the top of the event page again.
This is a common occurrence for me on Facebook on both mobile and desktop. It happens sometimes in Gmail too. I'm certain I could find a half dozen other examples given five minutes to go test.
Meanwhile HN happily preserves scroll position perfectly.
I think you might be using the term “SSR” in a non-standard way. In the context of JavaScript apps, SSR refers to an initial pre-rendering of the HTML of a SPA page on the first browser page load. Subsequent navigations in that same browser tab would render on the client just like an SPA that doesn’t have SSR.
You might be talking about what the JavaScript community has started to call “MPA,” which doesn’t seem to have converged on a clear meaning but seems to usually imply that some or all page navigations do involve a trip to the web server and an HTML response.
SSR isn’t actually rendering though… it’s generation of markup just like PHP does… sure sometimes it contains data to rehydrate the page just like early .Net components used to
The various JS frameworks seem to have taken a concept that was common and tried to rebrand it which just adds more confusion
In React I think it’s pretty fair to call it server-side rendering, to distinguish it from the usual client-side React render which manipulates the DOM. It’s just like that, except it renders to a string that can be returned in an HTML response (or streams: https://react.dev/reference/react-dom/server/renderToString#...).
It might be a little clearer now to call it “pre-rendering,” to distinguish it from React server components which also run on the server but which are quite distinct from SSRing client components.
Fullstack react frameworks aren't purely SSR - they're isomorphic JS apps, which can render an initial page load serverside, then use clientside routing, suspense, serverside components, and clientside rehydration to progressively update the DOM without a full page refresh.
They are basically delivered as SPAs, with an integrated, isomorphic backend-for-frontend service embedded in the origin server.
They just don't feel like SPAs, because they have a multipage (routing) framework, and isomorphic rendering means those paths can be directly loaded from the server - while any subsequent navigation just updates your UI clientside.
In the case of static conteent-based sites, that SSR can even be done ahead of time, as a static built-time render, and the pieces of data needed to load different pieces of content into the SPA ('pages') get dumped out as static JSON resources. That's what Gatsby offers particularly as its specialty versus next.js.
Next.js can also do Gatsby-like static generation, but also update those generated pages if the content changes in the backend. They call it incremental static regeneration (ISR).
Nor most of the commenters here. SSR on page load doesn't mean it's not a SPA from that point forward. Done right, pages will render appropriately either on the server or on the client with the same code.
Why do I hear so much about htmx and so little about unpolly, which seems everything htmx promise but with additional high level primitives for the common task?
Unpoly dev is german nobody cares about abd doesnt go on podcasts vs htmx author is american that does marketing well. Same goes for alpine js where the author is “famous” dev.
Pretty typical with open source projects tbh. Many of them win thanks to marketing more than anything else.
Don't why you have been downvoted, while there are famous dev outside of the US, american identity and marketting does sell better than the german one.
A lot of people still mix jQuery and React in the same parent project. Mostly just via legacy support when using existing serverside frameworks but still sometimes having the fallback easy DOM/event stuff is just easier when you need to get it done (keeping the HTML/views isolated from each other of course so you don’t mix concepts). It doesn’t sound pretty but they can serve dual purposes. I don’t know enough about HTMX on how it would work implementation wise though and what type of setup.
But htmx is all about replacing server rendered html with server rendered html partials. I would like to see what reacts vdom does when you keep ploping some partials into DOM it thinks it controls.
Yeah they’d have to be isolated from each other if that’s the case. Which would defeat the value if it’s a small project starting from scratch with a limited scope frontend-wise (which htmx typically implies whenever I’ve seen it used or mentioned).
Preact is the tiny alternative to React (I still think preact could be smaller if they only focused on hooks).
I htmx is too bloated, while it's much smaller than the React codebase - I want the tiny, <1k loc alternative that literally just makes working forms and href links into dynamic fetch() responses and maybe adds additional support for auto-refresh from websockets or SSE.
This comment thread is a little funny because every single HN thread outside of this one rants super aggressively about webpages that don't show any content before JS loads, but this thread has managed to collect the opposite group together for once because React's docs have updated to stop actively recommending tools that force that problem to happen.
I noticed that too. It’s a humble reminder to us that Hacker News isn’t one entity. It’s many people with different opinions, taking turns deciding when they want to be heard.
I'd like to see a browser extension or something similar for HN that would let one add tags to user names, and display those tags next to user names on comments and submissions.
I often see someone take a pro-X position in some discussion and have a vague recollection that I've seen them take an anti-X position in some other discussion but it would be too much work to go digging through their comment history to check that.
For example, people who argue we need to ban cars in cities and suburbs because they are dangerous for kids playing in the street but who argue against every proposal to protect kids from online dangers saying that it should entirely be the parent's responsibility to control where their kids go.
Or people whose strong criticisms of most police procedure go completely out the window when the discussion involves some kind of crime that they personally have been a victim of and there they argue for more surveillance and easier warrant requirements.
My guess is that a lot of cases it is just good old fashioned self-centered thinking. But some probably have some good justification for the seeming contradiction which could lead to some interesting and insightful discussion.
Yeah there was something like this for reddit. Maybe part of Reddit Enhancement Suite? Probably would be relatively easy to port that functionality for HN, or other sites with users.
Aidea: a chatgpt query builder that you feed a snapshot of your online discourse, the surrounding contexts and it tries to find things like hypocrisy/ class/culture blindness, in how you communicate.. or think.
This is not unusual for HN. I noticed that the bashing and praising Unix come in similar proportions.
If the publication criticises Unix, it's comment section lokks like Unix fans have the loudest voice. The other day, commenting on other publication, virtues of Unix have been forgotten, and the comment thread praises some alternative.
my observation is that the community (here) has converging opinions, but the groupthink changes over time. At some point it seemed SPA was all the rage, now there is a reactionary wave
SPAs, microservices, nosql (Redis), and serverless are all still alive and well, they just aren’t a hammer for all problems like (some) people treated them originally. Nerds getting overexcited about new tech is an old story and it will continue to happen indefinitely as much as we like to smug post about it.
IDK about GraphQL since I’ve not used it but I’ve read lots of stuff recently about frameworks/ORMs working to better support this type of thing more directly/natively.
Your comment sounds a bit dismissive though. They all provide plenty value individually. A lot of this stuff needs to be used IRL for the community to understand the limits and there will always be junior devs and cowboys willing to risk it.
Plus not all of it is merely overexcitement/immaturity either, small companies and small dev teams often try to keep their toolsets small and eventually end up pigeonholing stuff into tech that doesn’t fit, until they get time/resources to do it properly. Some things are more obvious in retrospect.
The vast majority of the software world is still pretty conservative when you look beyond HN and Twitter.
In your own, exactly what point did you tried to make? Complaining that x and y technology users joined the "whoops" crowd when those technologies are in fact well established and proved to be effective if not nearly optimal in some applications, what do you perceive as "whoops"?
Frankly, it didn't seemed you had a point to make other than parroting cliches.
Being too eager to dismiss a technology and move on is just as much of a bandwagon-jump as being too eager to adopt it in the first place.
The Gartner Hype Cycle[1] has both a 'peak of inflated expectations' and a 'trough of disillusionment'.
The thing a lot of tech cynics fail to spot is that both of them are wrong about the long term value of the technology.
The 'plateau of productivity' awaits, where graphql, nosql, serverless, and SPAs will join every other technology, finding productive use in their appropriate niche.
> The 'plateau of productivity' awaits, where graphql, nosql, serverless, and SPAs will join every other technology, finding productive use in their appropriate niche.
I keep thinking of the tower of babel.
> God was concerned that humans had blasphemed by building the tower to avoid a second flood so God brought into existence multiple languages. Thus, humans were divided into linguistic groups, unable to understand one another.
The signal is to avoid new technologies with marketing engines behind them for at least a few years. And anyone who is gullible enough to believe them, which are more likely the new people learning to code and yelling about the new shiny libraries they found than full time developers that are actually productive rather than bored.
In my experience it's the poorly implemented abstractions on top of your ORM of choice that make graphql a bad time. It itself is really a great way to do things imo
Yes, exactly. The typical issue is devs not grokking the mental model of GraphQL and instead just creating more and more extra queries, essentially resolving data piece by piece in the frontend instead of leveraging GraphQL types and adding types, fields and field resolvers as needed so that the frontend can do one query to get all the data it needs.
No wonder it feels like a clunky extra glue layer if it’s being used as one.
> and no one can delete anything because you have no idea what it'll break.
This is a problem with GraphQL, but you can monitor if anyone is requesting that data.
Major benefit with GraphQL is you can ask for the data you need and just the data you need. So you don't have 30 different API endpoints that really return the same data, just smaller chucks. Or maybe you just need the IDs... etc.
GraphQL is also efficient here, not executing the code for the data you don't need - which is really useful.
It depends if you're in that situation or not, or what parts of your domain are in those situations.
> Major benefit with GraphQL is you can ask for the data you need and just the data you need. So you don't have 30 different API endpoints that really return the same data, just smaller chucks. Or maybe you just need the IDs... etc.
Most sane REST-like implementations also support this, typically with query string modifiers like a "fields" param or similar.
A lot of them also support deep relationships this way too.
For example, the Directus REST API is completely feature compatible with the GraphQL API.
Again, as an example, Directus supports doing everything you just said over both REST and GraphQL.
There are many others that do too, and lots of libraries out there to make it easy to add that capability to your own endpoints in Node or.net or whatever.
You may also want to take a look at HATEOAS and JSON:API and similar.
REST-like APIs have long had feature parity with GraphQL and also superior mechanisms for caching etc...
Yeah just seems like a different interface than GraphQL, but it's basically the same thing as GraphQL. So at this point, is it just "we don't like GraphQL" or something?
I don't see the reason to have to homebrew this for most things when GraphQL has a fairly sane standard.
GraphQL is still over HTTP. You can actually even just use the concepts in the backend (and maybe Directus does??) and hide it from the user, if you think they have some aversion to POSTing JSON for a query.
> is it just "we don't like GraphQL" or something?
Yes.
But not without reason.
GraphQL departs from web standards and semantics in order to solve a problem that doesn't really exist in most APIs.
You incur a cost in using it, some of which I've outlined but there are many others, such as working against the browser's native caching capabilities, e-tags, etc...
This cost would be worth paying if GraphQL brought new and valuable capabilities, but as I've discussed, it doesn't really do that.
With REST endpoints, you have to really reason about entities and URL structure to design it properly. It's not easy, but it shouldn't be - it's meant to be a long-lived API contract based on document location, so you should spend time reasoning about the design.
GraphQL, in my experience (much like SOAP/WSDL) encourages lazy API development with the GetWidgetsByColorForArthurOnSunday() type functions. It requires additional libraries and tooling and a whole additional layer of complexity. It works against long-standing native browser functionality, and in many cases is just a solution in search of a problem since for most popular API consumption there's a client-side library that abstracts away details like transport.
Also, I personally dislike it because I can't use my preferred data mutation strategy, JSON-PATCH [1].
If you want the control and low overhead of Vite but don't want to implement everything a framework gives you, vite-plugin-ssr might be interesting for you.
It is basically Next.js as a do-one-thing-well Vite plugin (its slogan).
That looks perfect for what I was looking for on a side project. I hope they don’t end up bloating up over the years via endless user demands and turn into another Next.js. More like a Sinatra vs Rails.
Thanks for sharing this! Comments like yours are why I love HN comments. Despite all the arguments and negativity, I managed to find a useful comment which is directly applicable to my current needs!
I have been trying out Vite on my latest small project and was wondering if I should enable pre-rendering or perhaps alter the build process. I have markdown files which form some pages, currently they are imported and this causes the *.md files to be fetched when navigating to that page. It's mostly fine but it wouldn't be the best for blog SEO. So thanks again for giving me another option to look at, it may be just the right thing!
Integrating React into an MPA is quite awkward, surprised this is the target audience for it.
I love the potential of web development but of recent, it's been infected by hype-marketing and blog-engineering.
I get that it's become very accessible to write web applications and that's good for the growth of the platform - but it almost feels like this accessibility has led it to squander its potential in pursuit of unsophisticated and unambitious objectives.
Web developers today are distracted by premature over-optimisations (ignoring effective low effort optimisations) and language+platform features that are a great, but kinda useless from a project development standpoint (time/money/complexity/collaborative capacity cost).
As a result, platform developers are distracted implementing features that don't innovate the platform - so we sit and wait for the truly groundbreaking things that never come because we gotta discuss the pipe operator, or adding types to the JavaScript language specification.
Meanwhile projects that can't wait for the platform to evolve flood us with Electron apps that everyone hate.
sveltekit is the same, ssr first, i am so sad react now becomes ssr first too, i am forced back to vue,which still has a CSR SPA first, add ssr if you need it approach.
no i dont need ssr at all, internal tools,dashboards,embedded devices,etc etc have nothing to do with ssr,nothing at all
Those marketing pieces are becoming a bit tedious to decypher for me. The real message is not something about React SPAs but something about Wasp? Just tell me this thing about Wasp and don't distract me with something about React.
For most React apps, SSG is by far the best option. With Next.js it’s easy to do and takes less effort than a client-side app with a separate backend. SSR React was a PITA initially 2-3 years ago, but it, libraries and the frameworks have come a long way.
Nobody is forcing you to use all the capabilities. You can still use it for client-side only if you want, but the efficiency of having both is perfect for me personally and our company.
frontend is already complex enough, there are many use cases do not need SSR at all, React used to be SPA first, now is SSR first(just like svelte), which means lots of unnecessary stuff to understand for SPA programmers. I came from vue-svelte-react, now Vue is the only one still does true SPA(SSR is opt-in), so, I am back to Vue and hope it won't change to SSR-first like the rest.
React is owned by Meta which cares more about SSR, similar to Svelte. Vue is not owned by any single company, that seems like a huge huge plus now.
Obligatory "front end is a mess" comment. I taught at a bootcamp for 6 months, it was a great experience but when we moved on to react after vanilla JS the amount of incidental complexity was a huge step up, even with create-react-app. Now they push people towards adding a server side framework at the same time, right off the bat? I think there's a real danger with new engineers entering the industry that they have no chance to develop a proper mental model of the underlying tech stack the way so many libraries, frameworks, packages, bundlers are thrown together just to get something working. You think the docs should just start with using plain React, and then branch off in to SPA Vs SSR later.
React is for Facebook problems. Facebook is not concerned with "new engineers" at this time, nor have they ever really. Big tech contributes the least to education and pays little in taxes.
224 comments
[ 0.27 ms ] story [ 630 ms ] threadSure SEO is important for most people anyway, but having multiple pages that load instantly rather than having to wait for a server call is also pretty handy. Plus auth working better.
I don’t see why next wouldn’t be the default and react now the outlier.
I find the idea that you want to handle data fetching and routing in a framework to be reasonably convincing. There are advantages here, and it's easy to get into a bit of a mess if you just fetch data in each component.
The part that has stopped me from looking at the frameworks until now is that they add a lot of parts I don't need, and the documentation seems to be focused on the SSR part. And then there are React server side components, which is another new concept I need to understand. Maybe the frameworks are a good fit for my SPA use cases, but it'll take quite a bit of time to find out if that is true.
You can do the same in Gatsby, but it's probably a waste of time.
But...
With an index.html file containing a createRoot(document.getElementById('root')).render(<MyApp/>) call, and parcel or vite or webpack, you can produce much the same thing.
Possible that next.js will give you easier access to some more interesting ways to split your JS bundle up - but also possible it will fight you if you continue to insist on not taking advantage of SSR.
https://nextjs.org/docs/advanced-features/static-html-export
This reads to me like "Next.js can do SPAs (like CRA) plus static sites and SSR". Next.js' site even says "The core of Next.js has been designed to enable starting as a static site (or Single-Page Application)" [1].
0 - https://react.dev/learn/start-a-new-react-project
1 - https://nextjs.org/docs/advanced-features/static-html-export
We (just today) updated the Next.js docs linked based on feedback around this to make it more clear. Hopefully this helps, let me know if you have other feedback.
That said, I'm not sure why running `next export` is considered 'advanced'.
I'm not saying Next.js is doing that with static export, but I'm not sure they aren't either. It fits the pattern too well. I'm still suspicious about how the Image implementation (which nearly every website needs) breaks `export` and the only solution is "roll your own image handler." I'm not sure if that fits into the understandable lack off investment or the intentional difficult/obscure.
You can read more about how to use Image Optimization with a static export in the new docs: https://beta.nextjs.org/docs/configuring/static-export. There's a full example there with Cloudinary, but you could use any service you want.
I wanted to note that I'm not asking you to build this, I'm more sharing my use-case in case it's helpful feedback.
What would really be amazing for me is a build-time image processing pipeline. Any images I use for the static site are already present in the repo (none are user-supplied or come from object storage, etc). Since all the image info is present at build/export time, it would be amazing if the image processing were done locally during the build and then the next/Image tags would instead of invoking server-side code, generate the static <img> code necessary to reference the different versions (such as srcset, sizes, etc)[1]. There is at least one open source project to do that, but at least when I last tried it, it was essentially dead on the vine. I searched around but couldn't find any solutions, which was pretty disappointing. I did end up shipping the app and just manually pipelined those images and hacked out the <img> tags instead of using the component, but if I had more than a handful in the site that wouldn't scale too well.
Anyway, thanks for what you've done with next.js! it's really an incredible project and you've been an important part of moving the web forward.
[1]: https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimed...
[1]: https://www.crunchbase.com/organization/vercel
Just use vuejs which is the only one truly never forces SSR on you if you do not want to have anything to do with it.
[1] https://rauchg.com/2014/7-principles-of-rich-web-application...
[2] https://twitter.com/rauchg/status/1637136013083684864
[3] https://twitter.com/timneutkens/status/1636693508223270912
[4] https://twitter.com/dan_abramov/status/1636827365677383700
In the new market, there will be much more scrutiny on costs and the complexity that creates it. The prospect of hiring a “React Engineer” with 7+ years of experience to build a cookie cutter UI, will be just as questionable as forcing the front end and backend to use the same technology and framework governed by one single vendor.
I predict vercel will have a rough time.
Looking forward to see how this plays out.
For example, let’s consider a site with two pages. In the SSR case, if I click the link to page 2, then I have to wait a whole network roundtrip for the page to appear.
In the SPA case you can decide when you want to load the content for page 2: with page 1 (if it’s a small amount of content), if the user scrolls to a certain point, … it’s completely up to you. You can cleverly hide the latency so that when the user does navigate to page 2, it’s instant.
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes...
Building site with Next.js makes it simple to get a good perceived performance, the framework handles it out of the box.
Only people who haven't had to set all this up themselves think Vercel isn't amazing.
It is handling a LOT of devops heavy lifting for you.
Somehow the JS/Node dev community managed to re-invent JEE web profile, and is very close to re-invent Glassfish as well at that point, but worse because it didn't learn anything from Java enterprise... this madness needs to stop.
It just makes sense when you take react as what it is: a library. Now, if you want amenities like a router you need to build it yourself or use something existing. 99.9% of people want this, so why not point them into the right direction?
You need to pull in react, plus Babel standalone, and then you can use <script type="text/jsx"> tags, which means you can bootstrap react components onto your page. But you are going to be basically running a compiler in your user's web browser. That's fine if you want to run that way, but Babel has docs that explain why you probably shouldn't (https://babeljs.io/docs/babel-standalone#when-not-to-use-bab...).
All you need is these two scripts:
[Edit - also need ReactDOM, sorry: ]I think it would help if more react tutorials started from here, because it shows why you need a build process.
Here, as a JSFiddle: the React 'Hello World' they don't want you to see: https://jsfiddle.net/smLa1bco/
If you really need to use html with script tag, go with Vue/alpine
Off the top of my head, here are benefits to SPA:
- I can just serve a few static files from a CDN. Every user gets the same client.
- Most requests made by the application are actually smaller. I'm just loading the data I need, rather than the data, markup and styling.
- It's an actual client application talking to a data API. It's the same API the rest of my client applications are talking to, be it a mobile API, native, CLI, etc.
- It's a much easier mental model. Interactivity without having to give consideration to whether or not it will disrupt whether it can be rendered. I build my application like a realtime application and just make requests for the data I need when I need it
- I don't have to think about exposing backend secrets, or trying to do things I'm mistakenly assuming to necessarily run in one environment or the other
- I can be much more explicit about loading and caching data when I would like to
Even most of the cons of a SPA can be ameliorated. The biggest con is a larger up front load, but that can be mitigated by code splitting and lazy loading. The fact that it's a handful of static files means that the application is basically cached, too. And SPAs are for applications, not websites. Most people using SPAs want the application experience to be optimal, not necessarily their initial first time load. They want small requests, interactivity, live feedback. This is all possible with SSR, but nowhere near as simple.
React frameworks are mostly hype in order to justify using a particular PaaS. They’ve hired all the influencers and using it to their advantage.
There definitely are good reasons to use SSR and these frameworks, but a fully interactive web app that acts like a desktop app isn’t one of them.
All of that to say I have no issues with it and react is still awesome. It’s a view _library_ and works great for its relatively restrained API. Most of the new features are opt-in and I don’t really touch them (besides hooks).
I think a lot of the ire against SPAs and other flavors of JS heavy pages would dissipate if devs made a point of trying to not unnecessarily break browser features and when breakage is unavoidable, furnishing replacements for the broken features that are as good as or better than the originals.
"But all the frameworks support doing the good thing! But only people who are bad at it make bad UX!"—well, it's still happening. No amount of contempt for the people doing it changes that.
I’m surprised the criticism is still ubiquitous: it’s either 5+ years out of date or some people run into these terrible sites a lot for some reason.
For example, less than 2 years ago someone did a "Show HN" of a Shopify front end they launched for their wife that was literally almost entirely nonfunctional. Not exaggerating.
https://news.ycombinator.com/item?id=27182932
That’s not true. I wrote non-SPA web applications in the mid-aughts that maintained scroll position throughout server roundtrips, using JavaScript and storing the current scroll position in hidden fields upon submit. Even multiple scroll positions for nested panes. It also adjusted the saved scroll positions correctly when new elements were added to or removed from the page during the server roundtrip. This was encapsulated in a server-side HTML rendering framework.
This is a common occurrence for me on Facebook on both mobile and desktop. It happens sometimes in Gmail too. I'm certain I could find a half dozen other examples given five minutes to go test.
Meanwhile HN happily preserves scroll position perfectly.
You might be talking about what the JavaScript community has started to call “MPA,” which doesn’t seem to have converged on a clear meaning but seems to usually imply that some or all page navigations do involve a trip to the web server and an HTML response.
The various JS frameworks seem to have taken a concept that was common and tried to rebrand it which just adds more confusion
It might be a little clearer now to call it “pre-rendering,” to distinguish it from React server components which also run on the server but which are quite distinct from SSRing client components.
They are basically delivered as SPAs, with an integrated, isomorphic backend-for-frontend service embedded in the origin server.
They just don't feel like SPAs, because they have a multipage (routing) framework, and isomorphic rendering means those paths can be directly loaded from the server - while any subsequent navigation just updates your UI clientside.
In the case of static conteent-based sites, that SSR can even be done ahead of time, as a static built-time render, and the pieces of data needed to load different pieces of content into the SPA ('pages') get dumped out as static JSON resources. That's what Gatsby offers particularly as its specialty versus next.js.
I just want a quick way to throw some react hooks or web components into a dom element using a library that is less than 1,000 lines of code.
Pretty typical with open source projects tbh. Many of them win thanks to marketing more than anything else.
Plus i think US devs understand how important marketing is more than anybody else.
htmx is literally html extension. it is aimed at adding interaction to static html. Preact/react are completely opposite approach to that.
But htmx is all about replacing server rendered html with server rendered html partials. I would like to see what reacts vdom does when you keep ploping some partials into DOM it thinks it controls.
Preact is the tiny alternative to React (I still think preact could be smaller if they only focused on hooks).
I htmx is too bloated, while it's much smaller than the React codebase - I want the tiny, <1k loc alternative that literally just makes working forms and href links into dynamic fetch() responses and maybe adds additional support for auto-refresh from websockets or SSE.
I often see someone take a pro-X position in some discussion and have a vague recollection that I've seen them take an anti-X position in some other discussion but it would be too much work to go digging through their comment history to check that.
For example, people who argue we need to ban cars in cities and suburbs because they are dangerous for kids playing in the street but who argue against every proposal to protect kids from online dangers saying that it should entirely be the parent's responsibility to control where their kids go.
Or people whose strong criticisms of most police procedure go completely out the window when the discussion involves some kind of crime that they personally have been a victim of and there they argue for more surveillance and easier warrant requirements.
My guess is that a lot of cases it is just good old fashioned self-centered thinking. But some probably have some good justification for the seeming contradiction which could lead to some interesting and insightful discussion.
I’m sure there are some of my opinions do both. Some topics are complicated.
https://chrome.google.com/webstore/detail/hn-friends/ffgfcbf...
https://chrome.google.com/webstore/detail/hn-friends/ffgfcbf...
If the publication criticises Unix, it's comment section lokks like Unix fans have the loudest voice. The other day, commenting on other publication, virtues of Unix have been forgotten, and the comment thread praises some alternative.
Ignoring the noise is really becoming a key skill to survive as a programmer.
IDK about GraphQL since I’ve not used it but I’ve read lots of stuff recently about frameworks/ORMs working to better support this type of thing more directly/natively.
Plus not all of it is merely overexcitement/immaturity either, small companies and small dev teams often try to keep their toolsets small and eventually end up pigeonholing stuff into tech that doesn’t fit, until they get time/resources to do it properly. Some things are more obvious in retrospect.
The vast majority of the software world is still pretty conservative when you look beyond HN and Twitter.
In your own, exactly what point did you tried to make? Complaining that x and y technology users joined the "whoops" crowd when those technologies are in fact well established and proved to be effective if not nearly optimal in some applications, what do you perceive as "whoops"?
Frankly, it didn't seemed you had a point to make other than parroting cliches.
The Gartner Hype Cycle[1] has both a 'peak of inflated expectations' and a 'trough of disillusionment'.
The thing a lot of tech cynics fail to spot is that both of them are wrong about the long term value of the technology.
The 'plateau of productivity' awaits, where graphql, nosql, serverless, and SPAs will join every other technology, finding productive use in their appropriate niche.
[1] https://en.wikipedia.org/wiki/Gartner_hype_cycle
I keep thinking of the tower of babel.
> God was concerned that humans had blasphemed by building the tower to avoid a second flood so God brought into existence multiple languages. Thus, humans were divided into linguistic groups, unable to understand one another.
see? Now you can be wrong with the rest of us :)
No wonder it feels like a clunky extra glue layer if it’s being used as one.
I looked at graphql and saw a return to the horror of DoSomethingBecauseItsMondayAndDueTomorrow() type API methods.
Hundreds or thousands of them that accumulate like cruft over time, and no one can delete anything because you have no idea what it'll break.
I stick with well designed and well planned REST APIs.
It's not a panacea, but it helps.
This is a problem with GraphQL, but you can monitor if anyone is requesting that data.
Major benefit with GraphQL is you can ask for the data you need and just the data you need. So you don't have 30 different API endpoints that really return the same data, just smaller chucks. Or maybe you just need the IDs... etc.
GraphQL is also efficient here, not executing the code for the data you don't need - which is really useful.
It depends if you're in that situation or not, or what parts of your domain are in those situations.
I don't think "GraphQL everywhere" is sane.
Most sane REST-like implementations also support this, typically with query string modifiers like a "fields" param or similar.
A lot of them also support deep relationships this way too.
For example, the Directus REST API is completely feature compatible with the GraphQL API.
- Request the users, their IDs, and emails, and their post ids
Or:
- Request the user, tons of profile information about them, and the posts with all the info about the posts
You'd have to implement all this filter stuff for REST - and at this point if you have a bunch of different queries, yeah GraphQL makes sense.
Again, as an example, Directus supports doing everything you just said over both REST and GraphQL.
There are many others that do too, and lots of libraries out there to make it easy to add that capability to your own endpoints in Node or.net or whatever.
You may also want to take a look at HATEOAS and JSON:API and similar.
REST-like APIs have long had feature parity with GraphQL and also superior mechanisms for caching etc...
I don't see the reason to have to homebrew this for most things when GraphQL has a fairly sane standard.
GraphQL is still over HTTP. You can actually even just use the concepts in the backend (and maybe Directus does??) and hide it from the user, if you think they have some aversion to POSTing JSON for a query.
Yes.
But not without reason.
GraphQL departs from web standards and semantics in order to solve a problem that doesn't really exist in most APIs.
You incur a cost in using it, some of which I've outlined but there are many others, such as working against the browser's native caching capabilities, e-tags, etc...
This cost would be worth paying if GraphQL brought new and valuable capabilities, but as I've discussed, it doesn't really do that.
With REST endpoints, you have to really reason about entities and URL structure to design it properly. It's not easy, but it shouldn't be - it's meant to be a long-lived API contract based on document location, so you should spend time reasoning about the design.
GraphQL, in my experience (much like SOAP/WSDL) encourages lazy API development with the GetWidgetsByColorForArthurOnSunday() type functions. It requires additional libraries and tooling and a whole additional layer of complexity. It works against long-standing native browser functionality, and in many cases is just a solution in search of a problem since for most popular API consumption there's a client-side library that abstracts away details like transport.
Also, I personally dislike it because I can't use my preferred data mutation strategy, JSON-PATCH [1].
[1] https://jsonpatch.com/
I also think GraphQL should never be used for updating data, just that it is nice for a segment of problems related to querying data.
Use the @deprecated directive on your schema.
It is basically Next.js as a do-one-thing-well Vite plugin (its slogan).
https://vite-plugin-ssr.com/
I have been trying out Vite on my latest small project and was wondering if I should enable pre-rendering or perhaps alter the build process. I have markdown files which form some pages, currently they are imported and this causes the *.md files to be fetched when navigating to that page. It's mostly fine but it wouldn't be the best for blog SEO. So thanks again for giving me another option to look at, it may be just the right thing!
SNR benefits SPAs too.
I love the potential of web development but of recent, it's been infected by hype-marketing and blog-engineering.
I get that it's become very accessible to write web applications and that's good for the growth of the platform - but it almost feels like this accessibility has led it to squander its potential in pursuit of unsophisticated and unambitious objectives.
Web developers today are distracted by premature over-optimisations (ignoring effective low effort optimisations) and language+platform features that are a great, but kinda useless from a project development standpoint (time/money/complexity/collaborative capacity cost).
As a result, platform developers are distracted implementing features that don't innovate the platform - so we sit and wait for the truly groundbreaking things that never come because we gotta discuss the pipe operator, or adding types to the JavaScript language specification.
Meanwhile projects that can't wait for the platform to evolve flood us with Electron apps that everyone hate.
I have hope, kinda...
no i dont need ssr at all, internal tools,dashboards,embedded devices,etc etc have nothing to do with ssr,nothing at all
It’s disappointing to me they’ve gone so hard on server side.
It feels like Facebook use it server side so they’ve lost interest in being purely client side.
React is owned by Meta which cares more about SSR, similar to Svelte. Vue is not owned by any single company, that seems like a huge huge plus now.
With next.js, SSR is opt-in too