I'm trying to get Barba JS, alongside GSAP, implemented on my React website.
For reference, I have followed this video tutorial here, this tutorial of course, is not in React.
Here is my folder structure which showcases all of the relevant files for this transition effect:
theme
public
index.html
src
components
Header
Header.js
pages
Homepage
Contact
utils
anim.js
helpers.js
App.js
index.js
I have the following packages installed:
gsap - version 3.8.0
#barba/core - version 2.9.7
Current results
No console errors and no compilation errors.
When switching pages, there's no transition. It almost feels like barba isn't initiated.
Demo:
As the demo involves a few files, I have created a codesandbox here.
Edit:
Have updated my barba transition code and have added debug: true. Then, when hovering over my contact page button, the console shows the error: [#barba/core] Error: Fetch error at XMLHttpRequest.o.onerror?
import { pageTransition } from "./helpers";
import barba from '#barba/core';
export function delay(n) {
n = n || 2000;
return new Promise((done) => {
setTimeout(() => {
done();
}, n);
});
}
barba.init({
debug: true,
sync: true,
transitions: [
{
async leave(data){
const done = this.async();
pageTransition();
await delay(1000);
done();
}
}
]
});
Dificult to say but you can set debug: true, inside the initialization of barba so it will spit out logs of whats happening ;)
barba.init({
debug: true,
sync: false,
//views das paginas
views: [{.....
I have since concluded that Barba JS is not compatible with React. Seems like the library needs updating to work with React Router.
More details here
Related
In a Laravel 9 project I am loading Glide.js via my app.js file:
import "./bootstrap";
import flatpickr from "flatpickr";
import Alpine from "alpinejs";
import Glide from "#glidejs/glide";
window.Alpine = Alpine;
window.flatpickr = flatpickr;
Alpine.start();
If I initialise the Glide object in the same file with:
new Glide(".glide", {hoverpause:true, autoplay:2000}).mount();
It works ok on the page I want it on, however it stops Alpine working on other pages.
I assumed that by adding it to the Window object
window.Glide = Glide;
I could simply declare it on the page I want it but I get the
Uncaught ReferenceError: Glide is not defined error.
I've also tried importing via cdn in a script tag placed on my home view
<script src="https://unpkg.com/#glidejs/glide#3.6.0/dist/glide.js"></script>
<script>
new Glide(".glide", {
hoverpause: true,
autoplay: 2000,
perView: 3,
}).mount();
</script>
But this tells me that [Glide warn]: Root element must be a existing Html node and doesn't work either.
Js isn't my strong suit by a long shot and I have a lot to read up on and learn but would somebody be so kind as to give me some pointers?
Thanks in advance.
I solved this issue by only instanciating the Glide object if the target element exists.
if (document.querySelector(".glide") !== null) {
new Glide(".glide", {
hoverpause: true,
autoplay: 2000,
perView: 3,
}).mount();
}
I'm not sure if this is actually an issue with the plugin and my configurations, or if it is just standard behaviour.
I'm using react-i18next with i18next-http-backend to load translation files from the public folder. The lazy-loading is a nice bonus but I'm actually using the backend plugin because the files are managed externally (by non-programmers) and I can't know upfront which files exist. I'm not working server-side here so I can't read from the file system directly.
Problem: I have a collapsible section whose content is only rendered on expanding the section. When that content requires a translation file that was not previously loaded, the fetching of the file seems to trigger a page reload: it flickers and scrolls up.
It seems strange to me that the page is flickering because of fetching a file. I suppose that i18next is updating because it's loading a new namespace and that causes the flickering. Does that make sense? If so, is there a way to tell the http-backend all the namespaces (i.e, all the filenames in /public/locales), still keeping the lazy-loading? Am I missing something in my configuration?
Here's my configuration:
import en from './en/translation.json';
import de from './de/translation.json';
const localResources = { ...de, ...en };
const customLocalBackend = {
type: 'backend',
init: function (services, backendOptions, i18nextOptions) {
/* use services and options */
},
read: function (language, namespace, callback) {
callback(null, localResources[language][namespace]);
},
};
export const i18n = i18next
.use(initReactI18next)
.use(ChainedBackend)
.use(LanguageDetector)
.init({
lng: 'de',
fallbackLng: 'de',
supportedLngs: ['de','en'],
load: 'languageOnly',
debug: true,
backend: {
backends: [
HttpBackend, // load resources from /public folder
customLocalBackend, // load local resources
],
backendOptions: [
{
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
{},
],
},
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
keySeparator: false,
});
Thanks for any help!
The problem was caused by a <React.Suspense fallback={<div />}> that was wrapping the full react app. When a new translation was injected at run time, the fallback div was rendered, causing the "flickering".
I removed the wrapper and set react: { useSuspense: false } in the i18n configuration and everything is working as expected now.
I'm building a component library of just HTML snippet and corresponding js/css and I'm using Docusaurus to document those compoents. I have a document page for each component. On the document page there is an example of each component. I'd like to make the components functional (click events, keyboard nav, etc.) so I have attached the component javascript via a plugin:
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin-component-assets',
injectHtmlTags() {
return {
headTags: [
{
tagName: 'link',
attributes: {
rel: 'stylesheet',
href: 'https://example.com/css/component.min.css',
},
},
],
postBodyTags: [
{
tagName: 'script',
attributes: {
src: 'https://example.com/js/component.min.js',
},
},
],
};
},
};
};
In my docusaurus.config.js I've added my plugin:
...
plugins: [
'docusaurus-plugin-sass',
path.resolve(__dirname, 'src/plugins/docusaurus-plugin-component-assets.js')
],
...
This successfully adds the stylesheet and javascript in the correct locations. However the javascript never executes. It appears that my component javascript fires before the documentation app loads.
What am I missing? What is the correct way to add external javascript to documentation pages?
EDIT: I'm using "#docusaurus/core": "2.0.0-beta.0",
I struggled with this too (on Docusaurus v2). Eventually I understood what the Client Modules documentation was saying and did the following, which worked for me both for the initial page load and the page loaded after a navigation event. (Since this is a single-page app, it's not a full page load when you're just navigating around the documentation, and I had to handle that case separately.)
Create a new file at plugins/my-script.js (or whatever you want to call it).
Add clientModules: [require.resolve('./plugins/my-script')], to your config in docusaurus.config.js.
Insert code like this into your new file:
import ExecutionEnvironment from '#docusaurus/ExecutionEnvironment';
const doYourCustomStuff = () => {
// your JS code goes here
}
export function onRouteDidUpdate({location, previousLocation}) {
// Don't execute if we are still on the same page; the lifecycle may be fired
// because the hash changes (e.g. when navigating between headings)
if (location.pathname === previousLocation?.pathname) return;
doYourCustomStuff();
}
if (ExecutionEnvironment.canUseDOM) {
// We also need to setCodeRevealTriggers when the page first loads; otherwise,
// after reloading the page, these triggers will not be set until the user
// navigates somewhere.
window.addEventListener('load', () => {
setTimeout(doYourCustomStuff, 1000);
});
}
Then put your JS code inside the given function.
Caveat: your effects will still be broken when hot-loading changes from a yarn start dev environment. The not-too-painful workaround is to manually reload in such cases.
You can embed your components in Live Code block Docusaurus V2.
You will need to install the package using npm or yarn.
npm install --save #docusaurus/theme-live-codeblock
module.exports = {
plugins: ['#docusaurus/theme-live-codeblock'],
themeConfig: {
liveCodeBlock: {
/**
* The position of the live playground, above or under the editor
* Possible values: "top" | "bottom"
*/
playgroundPosition: 'bottom',
},
},
};
You can find detailed information about this process by using the link below.
https://docusaurus.io/docs/markdown-features/code-blocks#interactive-code-editor
It should be noted that this only works with react components.
First off, I'm a beginner with NuxtJS and front-end development in general, so it might be that I'm missing something - though I do believe I went through all the options before posting here. Apologies in advance if that is not the case.
I've been having trouble using installed modules that I've registered as plugins. For example, take mapbox-sdk.
After installing it with npm install #mapbox/mapbox-sdk, which correctly creates #mapbox/mapbox-sdk in node_modules, I register it in nuxt.config.js:
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Of course, I also create the mapbox-sdk.js file in plugins/, containing:
import "#mapbox/mapbox-sdk";
Then, in a page (say, myMap.vue), when I try:
var mapboxClient = mapboxSdk({ accessToken: MY_ACCESS_TOKEN });
which is the basic usage example in the documentation, I get:
mapboxSdk is not defined
in the console. This behavior extends to every single module I installed today, but is not the case for modules I had previously installed.
The reason why you're getting the error mapboxSdk is not defined is because there are a few issues with the way you've set up this plugin.
Docs here https://nuxtjs.org/docs/2.x/directory-structure/plugins/, they have some useful diagrams.
There are a couple of ways you can use this package.
Plugin
// ~/plugins/mapbox-sdk.js
import mapboxSdk from '#mapbox/mapbox-sdk'
export default (_ctx, inject) => {
// Exposing the mapboxSdk to your Nuxt app as $mapBox.
inject('mapBox', mapboxSdk)
}
Then in nuxt.config.js, same as you've already done.
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Then in your component myMap.vue
var mapboxClient = this.$mapBox({ accessToken: MY_ACCESS_TOKEN });
Directly in the component:
If you don't wish to use a plugin, the way that #kissu mentioned above https://stackoverflow.com/a/67421094/12205549 will also work.
Try adding this after the import to let Vue know that this method exists (in the same .vue file) at first
<script>
import mapboxSdk from '#mapbox/mapbox-sdk'
export default {
methods: {
mapboxSdk,
},
mounted() {
console.log('mapbox function >>', mapboxSdk)
},
}
</script>
Do you have it working in a .vue component at first ?
I have my angular project structure as below:
/(root or repo folder)
|_ projects
|_ mylib (this is the main library that will be exported from the repo)
|_ sample-app (created to consume 'mylib ' project to test that things work fine when 'mylib' would be consumed in other projects)
To handle application state I am using ngRx (of which I have only basic knowledge). The project is setup with Angular8.2.5, ngRx 8.3.0 and RxJs 6.5.3.
On doing npm start on the repo, sample-app project is bootstrapped and mylib project is lazily loaded.
Here is how I have initialized the app store/state
In sample-app/app.module.ts (inside sample-app project)
StoreModule.forRoot({}, {
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true,
strictStateSerializability: true,
strictActionSerializability: true,
},
}),
!environment.production ? StoreDevtoolsModule.instrument({ name: 'My Sample App' }) : [],
In mylib/mylib.module.ts (inside mylib project)
import { libReducer} from './shared/store/lib.store';
StoreModule.forFeature('libState', libReducer)
The libReducer is exported from mylib/shared/store/lib.store.ts file
export interface subFeatureOneState {
// some properties defined here
}
export interface LibState {
subFeatureOneReducer: subFeatureOneState;
}
export const libReducer: ActionReducerMap<LibState> = {
subFeatureOneReducer,
};
The only issue I am getting with this setup is that I get an error when I try to build my project( using ng build).
The error says
Checking the logs doesn't provide much help either.
The build issue gets resolved if I change StoreModule.forFeature definition in mylib.module.ts to below
StoreModule.forFeature('libState', subFeatureOneReducer)
But this is not what I desire as I intend to keep all my reducers at one place and just have one reference of StoreModule.forFeature inside mylib project.
I couldn't find much articles online that explain usage of ActionReducerMap for a feature module store. I followed the approach mentioned below, but it didn't solved the build failure issue:
#ngrx/store combine multiple reducers from feature module
Is there something wrong with the way I have configured store/reducers to be initialized? It would be great if I can get any pointers on this to solve the build error issue.
Here is my code I think you are missing the ROOT_REDUCERS
export const ROOT_REDUCERS = new InjectionToken<
ActionReducerMap<State, Action>
>("Root reducers token", {
factory: () => ({
router: fromRouter.routerReducer
})
});
StoreModule.forRoot(ROOT_REDUCERS, {
metaReducers,
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true
}
}),
Here is my full code for your reference