Does switching to Edge runtime disable SSG and SSR? - next.js

I started a simple project with Next.js 13. I only have one page with a simple h1 in it. Locally, with the default next.config.js I get the expected output - the h1 is in the HTML body. However, if I change the runtime to experimental-edge (or just edge either next.config level or on component level) my h1 tag is no longer in the HTML, but rather added later. Does this mean that I cannot use the edge runtime and generate the HTML on the server?

Related

Why are my Styled Components' generated class names colliding?

I usually build my Styled Components with a root <Container> tag. However, in my current project, class names generated by Styled Components with identical names are colliding.
For example, <FooWidget> will be styled with the Container styles of <BarWidget>.
This happens unpredictably, but deterministically. I.e. not all <Container>s collide, but when they do, they do so in the same way every time. I can fix this by changing the components' names or root elements, but then this eliminates the scoping benefits of CSS-in-JS.
I've never had this problem before, which makes me suspect in may have to do with server side rendering on Next.js, which I'm using for the first time. If I restart the dev server, everything will display correctly on the initial render, but then break and stay broken on first refresh.
I installed Styled Components according to the Next.js guide. I found this bug on Github that may be related: https://github.com/styled-components/styled-components/issues/3125.

What does _buildManifest.js in nextjs do, and can it be disabled?

We're building a site with NextJS, and noticed that in the source code of our website, we can find a _buildManifest.js file, which appears to list all pages currently defined on our site. We'd like this to not happen.
How is the _buildManifest.js file created, and what does it do?
How does it pull in the list of pages?
Is there a way disable its creation, and what breaks if we do?
We worked it out on our own, putting an update here.
It appears the build manifest is an autogenerated file that has a mapping of urls to the static JS chunk generated by webpack. This is primarily used for client-side navigation by the next/link component which, among other features, eagerly loads the JS on hover based on the href attribute.
The work is done by a webpack plugin defined here, which grabs all urls and generated JS chunks from webpack and spits out a JSON file.
As of Next v10, overriding this webpack plugin and filtering the output through an allowlist seems to work; the only observed side effect is that clicking these links must be done through a normal <a href> instead of the next/link component, which disables client-side navigation. This may lead to slightly slower page navs (no eagerly loading client-side JS on hover) but does allow for hiding the urls from a publicly visible endpoint.

How to solve "violate CSP directive: "default-src 'self'" in Angular 8?

We have an Angular 8 single page web app deployed on the customer server. They set one of the CSP directive to: default-src 'self'. We build the Angular app using ng build --prod like any other Angular applications. After deploying, we get this error:
main-es2015.47b2dcf92b39651610c0.js:1 Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
Look into the html code on the browser, I see something like this:
As you can see, Angular actually use tag <style> to serve the css (please correct me if I'm wrong). This violates the CSP directive mentioned in the question.
After searching around, I think Angular/React is quite bad at handling this issue, those frameworks are not built with CSP in mind. You can check out Angular github page, there is an open issue for this. Now I'm searching for a solution to overcome this, of course changing CSP policy is not an option because the customers don't want to.
How can I tell Angular not to use tag <style> in production to serve css? I think to make it works we need to set Angular in a way that it will load the css files, and then use styles in those files instead of injecting <style> into html which causes CSP issue.
Edit 1: Our project is using scss.
Edit 2: After searching around, I have found out that Angular will inject your component's styles into the DOM by using <style> element. As shown here:
Now I have an idea, because for each compinent's style will be injeced into the DOM through <style> element, we can prevent this from happening by bundling all component's style .scss file into a single style.scss file. From the image above you can see that we always have an empty <style> element, so if this works, we will endup with only one <style> element and a <link> element that link to our global style scss file. We can have multiple way to remove that empty <style> element before the page got rendered by the browser.
Now I'm stuck at configuring custom webpack to make this happen. We cant use ng eject to get the webpack.config.js file since Angular CLI 6. I've been using Angular CLI 8 so the only way for me to add custom configuration into Webpack is to use custom-webpack npm. I cant find a good config file that has the same output as my desire, please help if you know how to config webpack to bundle all component's styles scss files in Angular into a global scss file.
I think this can be an acceptable answer for my question:
First of all, my recommendation is stay away from using styleUrls. Angular will inject styles of your component into the DOM using <style> element. Secondly, if it's possible, you should know / ask for the CSP policy on the deployment server/environment. What I have been doing to resolve the issue (my project is reletively small with just a couple dozen of components):
Copy (one by one) relative link of components, put them into angular.json, in styles attribute. This is because Angular will bundle all styles in this attribute as a single css/scss file. I copy one by one because the css/scss file was designed to work with Angular View Encapsulation in the first place. Gathering all of them into one place might introduct unexpected issue, this will break the UI. Whenever copy a component style and put into styles, I check if the UI breaks because of that. This will help me narrow down the root cause if such issue happens.
For each component, after copy its component style file's relative path into styles, I remove styleUrls in #Component. This prevents Angular from injecting <style> into the DOM.
Caveats:
Gathering all styles into one single file and load them at once might cause performance issue. Luckily my company project is relatively small.
Now you need to document the new way of making styling work in your project.

React CSS Modules: any reason to -not- extract all CSS to a static file?

I have built my app with React Boilerplate, and have been surprised to find all my CSS modules are not generating CSS as I thought, but the CSS is instead generated from JS and embedded in the header of the page. The image below shows just some of the many, many style elements that appear in my header after the page has loaded.
For development, I can see this making sense for HMR etc. However, for a production build, it is not what I would expect.
I would think the most performant build (ie, best) would be a static CSS file alongside the js. In fact, in our production build there is a lot of stutter as the site loads and applies styles to the elements in a staggered manner.
It seems straight-forward to build a static CSS file, so why isn't it the default (especially for RBP, whose major claim is that it is production-ready). After 5 mins of searching I found https://github.com/webpack-contrib/mini-css-extract-plugin, which seems to do exactly what I want.
Is there a benefit to dynamically adding the CSS in the document header as pictured? Is there anything we would lose if we built a static CSS document instead?

Rendering issue in Chrome due to #Font-Face

I have a large scale application that is developed using Angular 4, there seem's to be an rendering issue exactly as mentioned in this post Angular 2 Chrome DOM rendering problems
.When I navigate using router from one component to another
, while this question has an answer already , I am still unable to solve this issue.
My Application structure is as follows :
app-home --- > app-main --- > app-sub --- > <router-outlet> (contents)
Each of this selector imports same mixin file which is used to import #font-face , while the solution mentioned in the above mentioned post suggests to use parent component and use ViewEncapsulation.NONE , I cant do the same thing since there is a usage of the imported font face in each of these components app-home, app-main,app-sub and subsequent childs as well. When I remove the #import statement from the .less files I get an exception like
Variable #helvetica-bold is undefined
Is there a workaround to make my texts appear normally in chrome when I route from one component to another.
You need to make sure the font import is only called once.
Hence, you should remove all the font imports from the mixin file as you have already tried in your answer.
But, you also need to ensure the fonts themselves are still present once in your app where all views can access it. You probably have a file like 'app.less' or something similar, that contains styles that are available in all parts of your app. Cut the font-imports from your mixin, and instead place it in this file (make sure the path references are still valid, they might need to be adjusted). If you do not yet have such a file, you will need to create one and load it once on app start.

Resources