NextJS - how to dynamically load different apps with dynamic routes - javascript

I have a multi-lingual application that I use exportPathMap but I want to transition to getStaticProps and getStaticPaths. My structure looks like so:
pages/[language]/[app-slug].js
However, [app-slug].js could be any of 20 different applications with unrelated code...
After reading caveats I thought, with pre-defining the getStaticPaths, I would be able to do:
-[language]
--[app1].js
--[app2].js
...
But it throws You cannot use different slug names for the same dynamic path ('app1' !== 'app2')
Is there any way to dynamically load the react app code based on path, or to have multiple dynamic files in one repo? (all static paths are known)
This similar answer to use query values won't work for my case, SEO and bundle size are top priorities.

Related

Dynamic routing nextjs react

Help me please.
i am working with next js, i need to make this structure in url sitename/catalog/category/group/product
category, group, product pages are created dynamically, after that I need to generate static pages with ready-filled html markup in the out folder via the 'next export' command. I want to get all category, group, product pages to make a completely static site. In the documentation, I did not find information about a large nesting. Please tell me how to do it. Here is my current structure and what next js generates for me
Is it possible to do this?
my file structure
pages
catalog
index.tsx
[category]
index.tsx
[group]
index.tsx
You need to create dynamic URL using [slug] for all dynamic variable in your URL component.
Check the documentation: https://nextjs.org/docs/routing/dynamic-routes
Once you use dynamic URL, you need to serve getStaticProps (for data as props) and getStaticPaths (for diff routes) method on page to serve the data.
Note: above method are only executed on build time, in case of next export also.

Is it possible to reload the router in a running ember.js app in order to update the path strings of routes?

I'm implementing multi-language support in my app, and I guess this is the last thing that I would need in order to be able to change between languages without reloading the whole app/page. (I already have a solution with full page reload.)
For a simple example let's say this is how my router looks:
Router.map(function() {
this.route('search', { path: t('search') });
this.route('item', { path: `${t('item')}/:id`);
});
The t function would be getting the correct translation for the given strings in the currently active language.
The structure of the route hierarchy won't change, the only things that need to be updated are the path strings. Application state should be kept, of course.
I'm wondering whether this is possible to do.
I am not %100 sure about the correctness of what I wrote but Router.map is executed and resources with the definitions given within this method is transformed to a DSL instance and that is then passed to the actual router maintained by Ember.Router itself. In order to achieve what you want I believe what we need is dynamic modification to the router even if it is just the paths you need yo modify not the whole route structure.
If you look at the following github issue, Ember.js no more supports dynamically adding routes (hence no dynamic modification to the existing ones I believe). With all that said, I believe what you want is not possible without reloading the whole app (hence losing the application state).

Meteor - How to exclude certain paths from being crawled?

In Meteor, I have installed the spiderable package, which allows the application to be crawled by search engines. However, I want to exclude certain paths from being crawled.
For example, example.com/abc/[path] should not be crawled, whereas example.com/[path] should be.
I am unsure of how to do this. One guess is to include a robots.txt in the /public directory, and use regex as described here. However, the url doesn't contain the #! as it did in this question. Is that relevant?
My current implementation is a bit more complicated, and it's based on the following quote from the package's README.md:
In order to have links between multiple pages on a site visible to
spiders, apps must use real links (eg ) rather than
simply re-rendering portions of the page when an element is clicked.
At the moment, when the page is rendered, I test whether there's a /abc in the root of the path, and then set a persistent session variable. This allows me to make all paths in my pages' links not contain the /abc prefix. When a link is clicked, it will check whether the session variable is set and append to the path in an onBeforeAction() function, which allows the right template to be rendered. In doing so, I am hoping those links won't be visible to the spider, but I am unsure of the reliability of such a method.
tl;dr - How to exclude certain paths from being crawled in Meteor?
It kind of depends on what you're doing with the folders you don't want crawled. If they're just going to be used on the server side, you can use the /private/ folder. If you want them accessible, but uncrawlable, you can build in access to folders with a /.period/ in them, which makes them invisible to Meteor, but you can access via the connectHandlers and webApp properties similar to my answer here.
If you want them to be processed by Meteor as normal (e.g. javascript files) but then be inaccessible to the spiderable package, I'd suggest asking in meteor-core.

React, async loading for multiple sections/views with different components

I'm having an issue thinking about the best way to architect a React app with multiple pages/views (still a SAP).
Let's say we have a simple app with 4 major sections (pages): dashboard, users, stats, comments. Each section has different components in it (think react components). For example, the comments section would have a hierarchy like so:
CommentsSection
- CommentsQueue
-- Comment
--- Text
--- Buttons
- CommentsApproved
--Comment
--- Text
--- Buttons
In a framework like angular for example, the 4 main sections would be split into partials, and loaded in an ng-view upon request, with their respective components inside. When landing on the homepage, the app would only load the dashboard view and upon the user clicking on a nav item, the selected route (i.e. app/users or app/users/:id) would trigger and the app will load the required "template-view-partial" (without a browser refresh).
Now in terms of React, how would this occur? it seems like ALL views and ALL their components would need to be available in a browserified JS file and the app can then update the DOM.
This seems terribly wrong, as we'd be loading all sections in the first load, even if the user doesn't ever need to get to that section. Granted, we could split it with routes on the server, and only serve the components for the page based on the route, but that would require a browser refresh, where as in Angular for example, it would happen without a browser refresh as the view is loaded asynchronously.
The question is, how can this asynchronous loading happen in a React-based app?
I think there's a few different ways in approaching this, I'll explain the approach that I am currently using for my work and side projects.
Instead of using browserify, we use a module-bundler called webpack (https://github.com/webpack/webpack). What's great about webpack is that it's like Browserify but can split your app into multiple 'bundles'. This is great because if we have multiple components/views, the user would just download the features they need for that particular view without having to download everything initially. It allows react-components and their dependencies to be downloaded on demand.
Pete Hunt wrote an article that goes into depth on the benefits of webpack when using it with React (including how to async load react components), and how it is similar/different to Browserify and modern build tools like Grunt/Gulp: https://github.com/petehunt/webpack-howto
I have described one solution using webpack here : http://blog.netgusto.com/asynchronous-reactjs-component-loading-with-webpack/
In essence :
use require.ensure([], cbk) to define code chunks; in the cbk, load your packages synchronously using require()
in your host component, load your asynchronous component in componentWillMount(), and set in in the host component state.
use it in the host component render, when defined on the state

Single Page Application Organization

Coming from the world of rendering views on the server-side, I can't quite get it to click in my head how to organize the CSS of a single page javascript application. I'm using AngularJS in this particular case.
When doing server-side rendering, it's relatively easy to divide out and organize your CSS files, you can have something like the following:
/css
/layouts
home.css
account.css
...
/components
buttons.css
forms.css
lists.css
...
/modules
account-bar.css
shopping-cart.css
...
and for a given page, say a shopping cart page, you can just include the layout file you need, you can pick the component files unique to the page, and include the shopping-cart module. This results in close to the exact CSS the page needs being delivered.
When it comes to the single page javascript application, I'm a little confused on a few points:
How do you make, say layouts, for each page of the application pages, without having it mess with other pages? Since the page doesn't reload, it seems difficult to make layouts using the generic html elements such as header, nav, section, article, footer, etc. Do you just have to avoid using those elements and instead make divs with separate classes for each page?
I guess this relates to 1, but when you're delivering the CSS (and the JS really) do you just concatenate it all into one giant file? Doesn't making a giant CSS and a giant JS file for a decent size application result in a huge loading time upfront?
I recommend organizing your app by feature, where each feature is an Angular module. See here for an example https://github.com/angular-app/angular-app:
+ src
+ admin
+ users
. admin-users-add.js
. admin-users-add.tpl.html
. admin-users-edit.js
. admin-users.edit.tpl.html
. admin.js
+ home
+ posts
. app.js # bootstrap with requirejs or browserify
+ assets
+ common
. index.html
To answer your 2 questions:
The header and footer would go in index.html (may be imported). For re-usable markup in Angular you'd build a directive that may be common or related to a particular feature. Think of views instead of pages; think of directives instead of containers and selectors.
Yes, for production, everything concatenated in one file, app.min.css and app.min.js
You need some tooling too. With Browserify the workflow is simple, require regular Common modules, then build your browser script.
Separate classes for each page sounds ridiculous :) Look at Twitter Bootstrap - see how they use css classes.
It's faster to create 1 connection and load 1 file than create few connections for loading few small files. New connections opening is a very time consuming thing.

Categories