Hey, welcome to Adventures in Angular, the podcast where we keep you updated
on all things Angular related. This show is produced by two companies, Top
and Aves and Onvoid. Top and Doves is where we create Top and Doves
to get top and pay and recognition, but working on interesting problems and making
meaningful community contributions. An Onvoid which provides remote design and software development services on
a performance basis, so clients only pay when tasks are delivered and approved.
In today's episode, we will talk about server side rendering in Angular all the
nuts and belts that comes with it. So we're going to talk about what
is hydration three rendering, attP caching, a lot of stuff that is baked
in that, and we will also try to cover some of the improvements that
we had to assr in Angler seventeen. My name is Luke Spaganini. I'm
the founder of Onvoid and you're hosting the podcast and joining me in today's episode
is armand Vardenian. Hey, everyone, seems like I missed a couple of
episodes. Yeah, it's always good to have you. It's nice because when
you join, I already know that it's gonna be packed with content. Every
time they join us. Like you know, Arman always joins them before we
start recording. He tells me, I have so much to say, and
I'm like, okay, yeah, well that's great. Thanks to the Angular
core team, we have content for years to come. I guess. Yes,
yes, they've been very, very busy. Okay, let's get into
it. So first, let's just explain what is server side rendering, because
I'm sure that there might be people out there that don't even understand what it
is. And then we can go into why it's important to benefits, pros
and cons, and then we can talk about the futures. So Arman,
would you like to tackle that question? Oh sure, I have recently relearned
a lot of stuff about service side rendering, and of course this is a
feature that has been long present in the Angular ecosystem, like the concept itself
with you know, but we have lots of new improvements and yeah, they
were going to touch them a lot. So initially it was like service size
rendering, why would we want it? So when we build like classical Angular
application, what we get is a client side rendered application. So what that
means is that, like in general, when you go to some website,
you would receive a bunch of HTML and probably some JavaScript inside, and the
browser will first render the HTML, and maybe the joscape itself will also render
parts of that page dynamically. So classically we just get some HTML and the
browser will just immediately proceed to painting it, rendering it painting in the viewpoort.
Okay, so that is of course perfectly acceptable. But the community and
all the cool UI people wanted like a mobile application feel in the browser,
and we get it with client side applications, with client side rendering or single
page applications like what we say right, and single page application don't really have
much of HTML. Essentially, you get like an index HTML file that has
reference to a bunch of jazsk files, and then those JavaScript files will render
our UI. So when I say these jazsk files we mean Angular source code.
We mean our own code that we authored in the with the purpose of
rendering some UI and adding some dynamic stuff to it. Okay, So in
that scenario, the jobs coupt will emulate everything that is related to the applications
life. It will render, it will provide routing, so if you click
on a link, you will sort of go to another page but not really
go to another page. What happens is that the content gets replaced and a
special API is used to push this new URL into the browser's history. So
it feels like you are navigating, but in reality you are not going anywhere
in They're not making new HDP requests, downloading the nutl page rerendering and some
and it's a cool thing. It's a really awesome thing. Evidence by the
fact that when single page apps like were created initially everyone was crazy about them.
Always make a single page app with make a single page ap. But
like with any think, it has its own downside. So one huge downside
is the SEO problem, the search engine optimization problem. Essentially like web crawlers
like Google and Being and so on. When when we search on Google,
it has a big database of websites with keywords, so this is found on
those pages and so on. So how they know those pages have that content
is that they use a program it's called like a web crowller that would go
around the web, find new pages and index them into the database. The
problem with web cross is that those webcalls usually are like browsers. They will
get an HTML page and they will record whatever you have on your page.
Okay at indexing then the future, if you have I don't know, a
cooking website, someone searches something related to cooking, your website would probably be
found somewhere in the Google's database. But the thing of page application, as
we mentioned, they deliver only just MPTHTML with some JavaScript, so often web
crawls we just say, oh, you know, this is like an empty
page. So your single page application most probably will not be ranked and indexed
by Google. So yeah, that's a big blow if you are creating a
website that is not like a like not an enterprise solution, but more like
an e commerce or marketing or whatever that you need people that need traffic.
You need people coming to your website. And if people cannot find your website
on Google, your toast right. And so that's just one problem that we
didn't have the server side approach when we had all the HTML. And of
course another problem is the initial page load. So with when you get prepared
HTML file, it's fast rendering it immediately persistent rendered HML. But with client
side rendering we had an MPTHTML file, then you have to down a lot
of bunch of JavaScript. Then that bunch of JOBSRIP needs to be compiled,
and then it needs to run, and then it will start rendering the UI
and again after it has finished rendering. It works way faster and smooth than
service side rendering when you have to like throw away the old page and build
one. But this initial loading process is slow. And for again, for
website that depends on traffic loads that want more users that want clicks, that
want like marketing stuff and so on. Initial page load is a very crucial
metric, Like people don't like websites that load in like five seconds, okay,
And that's pretty understandable. So it went back in the day, Angular
only had spa single page. But I don't exactly remember from when we got
Angular Universal. Angular Universal previous solution for Angular in with service side rendering.
What it meant is that Angular itself is rendering engine. Cannot only run in
the browser, which is understandable for us, Like in the browser, okay,
it uses like document, the ed element, create element, blah blah
blah. It's understandable for us how it works in the browser, but it
also can work on other platforms. It can work on a server like like
a node engine node rendering engine like we have like pug right or stuff like
that. It can work like that. We can tell a node Jazz server,
you know, use Angular to render HTMO pages on the server side.
And it's really possible because when we go to the main ts file, usually
in a classical setup, you will see some imports from Angular slash Platform Browser.
A platform browser contains all the stuff that you need to run your Angular
app in the browser. So if you're building for a browser, then sure,
no problem use Platform browser. But you can also use Platform server and
you can use Angular Universe. So what you could use Angular Universal before v
seventeen. Okay, you can do service side rendering with Angular. You can
have a server like not j just server that would render the pages in the
back end and then serve prepaired content. Okay, so this is essentially what
server said. You rather up the service side, you serve ready HTML and
both your SEO and initial pageload improved significantly. That's what service rendering is in
this context. Okay, Okay, so if we try to summarize and kind
of condense everything, Basically, when you're coding Angular, you have single page
applications which are rendered in the browser, which means that if you inspect the
HML that is being returned from the server. Instead of the old days with
PHP and passion servers, where you would have the HML with all the information,
you only have the HML like referencing script tag, and that script tag
contains everything. So that is a problem for crawlers such as the Google crawler,
because it's harder for them to index your website to understand what content you
have so that they can show you in the search results. So server side
rendering is a way for you to instead of returning this MTHML, you can
make sure that in the initial page load, it already returns all the rendered
HML that the page is going to have, so that both improve improves your
ranking on search engines and it also increases your uh. This increases the speed
of the first the what's the called the first time to render? I forgot
the I know, I guess you refer to time to first bite that that
can also be improved. But with another technique. I think it's like initial
pagelo isn't initial? Yes, that's the one. Yeah, okay, so
these are are the main benefits though, yet, now what are the cones?
U service arren sound school, who should not do it. The interesting
thing about the cones in this scenario is just whatever I say about like,
oh, you know right now this is a downside. It's either a problem
that has been fixed so they don't really have it anymore, in like virgiency
teen or seventeen, or it is something that's going to be addressed anyway.
Okay, let's talk about some things that you need to consider. I wouldn't
exactly call those cons but those are things that you need to be mindful of.
In general, your Angular components will be just rendered on the service side
without a problem. So if you're using just Angular I like using template and
bindings and whatever, you have no problems in that regard. Angler would just
easily render that on the service side, no questions asked. The problem comes
when you sort of try to leave Angular itself inside an Angular app and try
to, for example, manipulate the dom manually. If you say, I
don't know, document query how it's called curry selector and find an element and
maybe change a property, or I don't know, manually remove something, and
that is something that might happen. That is a scenario that I mean,
Angler is great, but sometimes you want to manually do something with the I
mean virtual scrolling, whatever might. You might need to do that anyway.
It's not a very popular scenario, but it isn't unheard of either. So
the problem is if you start coding like that, if you reference window,
if you reference document and so on in your code, well that's not going
to work on the server. Server doesn't have a document object. It's a
server. It's not a web browser document and window and navigator history and so
on. Those BOM or dome APIs they only exist in a browser. Like
you couldn't access, for example, file system in the browser, right,
it's not jazz thing. So the same goals the other way. You cannot
access DOM because what don't there is no document object model on the server side.
So if you have to do this manipulation, it can get kind of
tricky depending on what you're trying to do. Well, it used to get
kind of tricky until version sixteen because now the problem was that you usually put
that sort of code in life cycle hooks. Okay, because if you put
that code in some method and then call it that method only when the user
clicks on a button, for example, then you're guaranteed that that code will
run only in the browser. Right, So okay, that sort of code
wasn't the problem even previously. But what if you want to do that manipulation,
for example, when the component starts rendering like engelining it. The problem
with anginet is that it's gonna also run on the server side, okay,
and on the server side you're going to get an error saying a document is
not defined. Like what are you talking about now? Starting from angle or
V sixteen, we have two methods after render and after next render. Well,
not exactly method they are just functions which can take callback, and those
functions guarantee that the collbeck only runs on the client side. Okay. You
can just put those functions in the constructor and provide any callback and you're guaranteed
the cobeck will only work in the browser. So now you're actually okay,
this code only client side, and after next render works only once, and
after render works after every rendering cycle. Okay. Essentially, in the end
of the day, they're just a mild different behavior, but they they're the
same. They provide you with the capability to clearly say, oh, you
know, this code is gonna work only in the browser. So that's probably
the main problem that people encountered with, you know, service side rendering when
they wanted to do manual no manipulations and so on, And of course it
has a bit of a learning curve, but it's not that hard, like
you don't add lots of overhead your projects for that s. Everything works as
it used to. You just gotta be careful about the client side versus service
side thing. And now we got us covered. And the good news is
in Angular seventeen, those two functions are now stable, so feel free to
use them if you're doing sssor and Angular seventeen. Yep. Another count is
that you're putting more load in your server which is serving the front. So
right now, if your server is just sending out static files, then that
is so much easier, like the server can just cash that and return it
kind of immediately. But if you're trying to do server side rendering on the
spot so that means dynamics service are rendering, then once you make a request,
the server will have to render the entire page before returning it. So
all the work that the client's browser would have to do to paint the page.
Initially, this will be done in the server before it gets returned,
so that might decrease. Well, it's definitely going to decrease the amount of
requests per second that your front end server can return to clients. The good
thing is that since all those things they are stateless, you can just have
more of those servers running in parallel and put a load balancer in front of
them, so it's not really a scalability problem. But if you have like
a lot of users requesting your website at the same time, then you're going
to have to think about cashing those pages, catching the rendered pages, or
deciding if you want to really server side render all of the pages are just
some of them. Maybe you can like pre render like the homepage or something
like that, and then you can serve that, but the rest can just
serve it and let the client render in the front end, so you can
have a fine grain control if you choose so. But yeah, it's definitely
gonna your server is definitely gonna take a hit. It's it's really awesome that
you would mention that, because especially pre rendering, because the funny thing is
that in Angular seventeen, well, now Angular universal is Gonne. We have
a package called Angular slash SSR built in, and with Angular SSR we have
pre rendering websgy sthetic side generation, and we have this pre rendering by default.
Actually the default option is pre rendering. So what happens there is that
when you build your application. I'm not talking about like serving it on a
server where when you run an engine build, what angular SSR would do is
it would go through your routing, find all the pages that are not parameterized,
So all the routes that don't have like pas parameters. Okay, not
the paths that have like slash id or what happened, just casual paths and
pre render those pages. Okay, you can pre render those pages, and
that agetme. Like if you have a homepage. You mentioned a great example.
A homepage usually like looks the same, okay, and even if there
are whatever differences, we can for example resolve them on the clients. We
just want to serve the page immediately. Well, now you can have the
homepage pre rendered. Even better than this if you have like a limited set
of collections, like you have a parameterized route, okay, but you know
that those parameters are predetermined, so not like a user idea that could be
anything and you could have any number of users. But no, like you
have some options that there are like four types of this parameter. You can
have a category of blog. Yeah, exactly, like you have a I
don't know a web store, and you have a category of I don't know
closing items for example, and you know all your categories, you have like
twenty two of them. Okay, you can just create a routes dot txt
file and put all the available options there and Angular will now go and say,
okay, I can now discover these route I can now pre render them,
render the page for this category, that category, that category, whatever
your parameter is, and pre rendering is actually by default so you don't even
need to worry about it. You can if you build a static website,
like if you're building a personal website, you can just SSG your application.
You can just add angerssr build your app like usual Angler app, and then
run engine build. Okay, you have a in the disc folder, You're
gonna have a browser directory, and we'll just have all the stuff that you
need to put in the server to serve for the potential clients. And this
is really awesome because it solves all the problems that we kind of have with
Like, look if we again with the clients side rendering. Obviously, yeah,
server is only serving like static HTML that will now want the client resolves
blah blah blah and do everything on the client. But your server is probably
a more capable computer than whatever your users are running. Right, So if
you free render, if you do all the optimizations and now only that really
mixed stuff is left to render, as you said on Spot, then you
have got yourself a very cool peal like your serve isn't gonna suffer dead much.
Yeah, and again that also has some caveats. For example, if
you pre render and you just return the cached pre rendered assets, then you
can't serve different For example, okay, homepage, let's pre render that.
Okay, but what if this homepage shows a widget that is specific to the
authenticated user. Then you can't really do that because you're pre rendered. It's
gonna it's gonna be like an unauthenticated pre rendered version of the page. So
if you if you have major differences in case the users are authenticated or not,
then you're definitely gonna still have to rely on that rendering. Uh,
interesting that like each caveat you say, we just move one step to the
next improvement to hav in SSR, we resolve that problem with the client side,
and specifically client side hydration, and it's now way cheaper to solve that
problem. Essentially, what like what you're saying is that obviously on the server
we cannot render authenticating content right for example, well, who knows if the
user is authenticated or not. What we can do we can use a combination
of the functions that I mentioned. We could use a buoy and flag and
only check for that stuff on the client side. Then we can use pre
render to pre render the static parts of the page. And then on the
client side we gotta we gotta enjoy the benefits of client side hydration, Okay,
and we can be sure that this problem is going to be resolved as
fast as possible. In the context of you know, miss a whole client
side re rendering process, I feel like we need to start clarifying what client
side adoration is. So the thing with like the main problem actually that we
didn't touch that existed previously with SSR in Angular. What's the following So even
if you build a server side application when the client gets the page, we
still want them to enjoy all the benefits of client side Angular. We want
the dynamic page. We want like if you click on the bottom, we
want to pop up to come up, and the dialogues to works, and
the single page navigation to work, and so on and so on and so
on. So the thing is it wasn't really possible previous like it worked,
but the way it worked wasn't very good. So what would happen is like
if you have a client set application purely single pay job. What happens is
that your templates that you create, they get translated to some JavaScript code that
an Angle uses to actually render this UI that you have. And Angular checks
for bindings. So we have bindings in our code, like we bind some
HTML element properties to our class properties, like in components we do text interpolation
and so on. There are different we do event bindings and so on and
some. So when Angular on the client does the rendering, the bindings are
really easy. We can just imagine that every time it encounters a binding in
your let's say template, the JavaScript that got translated from a template. If
all just let's say, I'm just saying it as an example. It's not
exactly how it works, but let's say it just keeps the reference to this
binding in an array. So next it can just go through that array and
see, oh, okay, this binding changed, I need to show new
UI. And that's how Angler is dynamic change detection and so on. And
that again is easy because Angler already is rendering those dome elements in a browser.
Okay, so it will just take the reference to the dom elements and
say, okay, here's a binding. I will update this domb element when
blah blah blah, something happens. But it's service side rendering. You've got
to resolve a problem. You already have all those dom elements. Okay.
So Angler is not rendering anything on the client side, So how is it
going to bind to all the stuff? And now, okay, that button
has an event listener. I've got to listen to its quick event. So
turn it out. It couldn't so in order for the bindings to work,
what would happen previously, prior to Angular v sixteen, what would happen is
your application HTML would come from the server rendered. Okay, you have nice
SEO, you have nice initial page load. But now Angular on the client
side will be download the Angular code itself, and then it will just demolish
the page essentially under the hood, and re render it again from scratch as
it would in the client side scenario. Of course, it had optimization and
so it wasn't that bad, but it still wasn't like the optimal scenario,
like you have the HTML prepared, why would you want to throw it away
and rerender it again now on the client side, And it of course worsened
some other metrics like time to interact it. You would still wait for jaoship
code to download. After that, you would wait for it to compile.
You would wait for it to demolish the page, build it again and all
the bindings and now it's interactive. So those other metrics improved, but these
metrics actually got worse with what our setup with previously. So for that reason
we now have what is called client side hydration. So what hydration does is
essentially, instead of throwing away your application dome that you got from the server,
there is a process that Angular uses. If it says that okay,
I'm going to hydrate instead of throwing it away and re rendering it, will
discover the bindings inside this template, I mean tablet inside the HTML, the
prepared HTML that you got from the server. It will find the bindings and
lagged onto it and continue working as if it had rendered those domb elements.
Okay, and that's actually really cool thing. And the most awesome thing is
that, like to enable it, you just need to add provide client hydration
in your main ts file and that's it. You don't need to do anything
like literally, you just add provide client side adoration and it works. And
the good news is from Angular v seventeen, client addation is stable, so
again feel free to use it in your production code. Basis API is not
going to change anymore. So yeah, that's a really awesome addition because now
not only you have the benefit of server side, but you have also like
very decent time to interactive metric, very decent largest content FORUL paint metrics.
So you're not gonna show pig image and throw it away. We render it
again, show the pig image and in a case so like heavy website that
have some flickering and whatever, all those problems are sold the plandside aderation and
it goes even further right because it's not just reusing the ATML elements that were
already there when the application was bootstrapped. Is more than that, it's also
reusing the attP requests that were made in the server when it was being rendered
on the server. So there's actually a way for us to enable attP caching.
I think it's much easier now, but in previous versions, if you're
still on previous versions, there's a state transfer module I think that's what it
called. And basically what this does is it transfers the data that was made
during the requests made in the service I rendering process into the front end so
that when the front and loads, it can reuse the data that you the
server got from these requests, so that the front end doesn't have to remake
those requests because they were already done when it was being rendered on the server
side. So yeah, that's basically like one step further into the hydration because
it also kind of hydrates even the data itself, not just the snapshot of
the elements. It's actually not even an option, like if you enable clients
a client side hydration, you get HDP transfer cache by default. Actually,
if you don't want it, you have to manually add like no cash.
There is a weed transfer options function that you can add to your provide,
provide clans, set hydration. Actually they're so like niche but really cool features.
Pretty cool options there. For instance, you can you can add well
by default it only catches get and options requests, right, So it makes
sense because usually you make post requests, the lead requests and so on.
You make those types of requests to modified data in the database, not to
change something in your HTML. And it's the requests that are kind of the
ones that are impacting your UI. But you if you are in a scenario
we're using a post request to a post method request to get data actually,
which is a scenario which feels odd but happens way more often than we might
think. One reason, by the way for that is that if you're using
query parameters, query parameters are limited in size, so if you have too
many parameters for a get request, you just kind of have to convert into
post requests instead of full body. So if you're in this scenario, you
can just add cash HTP for how it called me. Yeah, you can.
You can add the include post requests option. Just make it true and
it will going to cash post requests. On top of that, the headers
are not cased by default, but if you need the headers. Okay,
I can see that Arman is having some connection issues. But yeah, let
me just summarize this and try to bring another way to fixate this knowledge in
your minds. So basically, hydration is imagine that your application is literally in
the desert. Okay, so when you do servers are rendering, and you
return all that already rendered HML to the client, all that all that HML
is not not interactive yet, like it's not listening and handling client interactions.
For example, let's say that you render from the server and then you return
a buttom, if you try to click on the bottom, it's not going
to do anything because the bottom element is being rendered, but it doesn't have
a click event listener attached to it. So it's almost as if you have
all the structures, but they are dead, almost as if they are dry.
They are dehydrated, okay, and then the hydration process is kind of
like bringing that back to life. So in the hydration process, you will
it's almost as if you have a lot of plants and they're like super dry,
and then you water them and they come back to life. So that's
what Angler is doing, instead of of cutting down everything that is there and
recreating everything, is keeping those structures there and just bringing them back to life,
re adding the event listeners to them so that they can become so that
they can become interactive again. So this is what client side hydration does.
And then another benefit that we get from Angular specifically is that it not only
hydrates the elements, meaning that you don't have to the browser doesn't have to
recreate those elements, so it's faster, but it also caches all the attP
responses not all, sorry, by default, it catches the get request responses
that the server got during the server side rendering process and it transfers them to
the front end so that the front end doesn't have to make those requests again.
So this is what client side hydration does. And well, I think
we can actually start wrapping up from here because most of the major points that
we needed to cover in terms of service side rendering specifically with Angler, were
already covered. So I don't think there's much else that we can go in
here. But yeah, in general, so oh and Armen is back.
But yeah, I was just trying to summarize everything that we discussed and try
to give everyone kind of a guideline as to how to choose if they're going
to implement service I rendering their applications or not. As Arman said, implementing
service rendering has become much easier than it used to be, but it's still
not a super easy process, and it's very important, for example, that
the libraries that you're using, if you're using third party libraries, that they
were made so that they can work in the browser and also on the server.
Otherwise, if the libraries that you're relying on are trying to access browser
APIs such as the Window Document, etc. Then they're going to fail and
you won't be able to service side render. So if you're starting an application
from scratch, I would recommend to enable it just because you get some performance
benefits and then you already start with the most strict setting possible. But if
you already have a big enough obligation that is not doing service side rendering,
it's definitely not a very trivial process to convert to it. Unfortunately. I
mean, to set up the initial structure is pretty easy, but to make
sure that your entire code based works on the server. It's not that easy
because maybe we're talking about years of developers working in the SCO based without having
to worry about wrapping around their calls to document in window APIs, which,
by the way, you can't access. That's one important distinction that I don't
think we made ARMEN. You can still access the document the window, et
cetera. You just first you either do it in the way that I would
recommend as a best practice, which is you can inject the document from Angular
Core and that way, if you're on the server side, then you're going
to get not like the native browser document, but an object that simulates the
document on the server. Or if you really only want to access it in
the browser and you don't care about accessing it in the server, then you
can either use the life cycle hoops the arm discussed the Armen mentioned before,
or you can inject the platform i D. So in your constructor you can
inject the platform and then you can call function from angler which is platform browser
and you pass the platform i D and then if you're running on the browser
is going to return true. So you can just wrap it in this if
statement and then you can own you can have part of your code that is
only going to run in the browser. So that's that's actually very common to
be done, even if you're doing service are rendering, because there are things
that you only want to do in the browser. For example, I have
four or four pages that they have a timer to redirect the user to the
homepage. So you go to the four or four page and then it has
like a ten second timer and it shows, hey, we'll redirect you to
the home in ten nine. Hey I can't do that on the server because
if I do, every request takes ten seconds because it's like waiting for your
observable to end, and then it always returns the homepage instead of the four
or four So that's the kind of thing that you want to only run in
the browser. So you can always do those things, but it's definitely something
else that you have to keep in mind, and it also increases a bit
the complexity and understanding of your cod base by the other developers. So it's
definitely not a trade off that we can easily discard. I think it needs
to be to be considered, but I would definitely recommend service side rendering your
applications if possible. I think the same. Actually, if you are,
especially if you're working on your own product, it always could be beneficial to
keep service rendering in mind. I mean, obviously, if you know that
the solution is not intended for public cues, if you don't really care about
the metrics, then probably you don't need to worry about it. The cool
think is just now also easy to add services side rendering to an existing project.
Well, in the sense that you can't just run a JADA and your
RECESSR. It will generate the stututnit service side. Then you can sort of
address the things that you need maybe to change or migrate a bit to work
better with as a star I guess scenario you mentioned. Of course, it's
always gonna have problems in some part of your application. You probably have something
that isn't really tailored to work on the service side, so you've gotta be
careful about that. But the process of adding and then getting to the actual
starbut F is quite easy now. Yeah, yep, I agree. Okay,
I think that that Arman. Do you think there's anything else that we
need to cover before we finish this episode? I would just mention, uh,
the other things that probably are on the horizon for clients for SSR in
general. So the client side hydration that we mentioned is a full hydration,
So the entire app that you have, all the bindings are going to get
rehydrated, which isn't bad, it makes sense, but you could get even
better time to interactive metric if you do like partial hydration, for example,
hydrate only the bindings that are in the viewpoint and continue hydrating in rest and
stuff in some other scenario strategy. And probably I'm not I'm not sure when
or how, but it is possible. It's probably a goal of the team
that is working on the SSR package to get us also partial client side hydration,
and I will be going to further improvement in all of this SSR thing.
Yep, that's really interesting. Okay, all right, let's go into
promos. So my promo is just going to be Onvoid, so it's u
N void dot com. If you're interested in staff augmentation or just fully outsourcing
our project, Void can do that in a performance basis, So clients are
only going to pay after the tasks are delivered and approved. So if you
don't appreciate the quality of the work that was delivered, you don't have to
pay, so you're completely protected as a client, which means that they're actually
going to deliver that because if they weren't going to be able to delivered a
good quality, why would they offer that guarantee? Right, So yeah,
if you're interested in that, go check out Void dot com, U n
v O I D dot com. How about you, Arman. I think
in a week or two, I'm going to have a pretty big announcement,
especially for people who listened to this podcast and are stuck on some earlier Angular
versions. I wonder how to upgrad what new stuff is going on Angular.
There is some cool stuff that is coming your way and I'm gonna I'm gonna
have a link to that great stuff and after that I will make the announcement.
So hopefully maybe next week or the other one. But it's a pretty
big thing, so you know, stay tuned. Nice, Nice, I've
been waiting for that for a while. Okay, I want to break the
news to everyone. Okay, okay, y wait a little bit longer,
Armen. Okay, again, thank you so much for being on the show,
Man. I appreciate every time that you can join. You always bring
a lot of a lot of content for us. Yeah, it's always great
to have you on the show. Oh, no words, It is always
a pleasure, all right, Thanks everyone and until the next one.