custom ckeditor5 build is not working with nextjs - next.js

how to implement custom ckeditor 5 with nextjs in functional component.
ClassicEditor: require("#ckeditor/ckeditor5-build-classic"), //working fine
ClassicEditor: require("../ckeditor5/build/ckeditor"), this is not working
this is perfectly working
import React, { useEffect, useState, useRef } from "react";
function Editor() {
let editorRef = useRef();
const { CKEditor, ClassicEditor } = editorRef.current || {};
let [loaded, setLoaded] = useState(false);
useEffect(() => {
editorRef.current = {
CKEditor: require("#ckeditor/ckeditor5-react").CKEditor,
ClassicEditor: require("#ckeditor/ckeditor5-build-classic"), //working fine
};
setLoaded(true);
}, []); // run on mounting
if (loaded) {
return (
<CKEditor
editor={ClassicEditor}
data="<p>Hello from CKEditor 5!</p>"
/>
);
} else {
return <h2> Editor is loading </h2>;
}
}
export default Editor;
But custom builder is not working
import React, { useEffect, useState, useRef } from "react";
function Editor() {
let editorRef = useRef();
const { CKEditor, ClassicEditor } = editorRef.current || {};
let [loaded, setLoaded] = useState(false);
useEffect(() => {
editorRef.current = {
CKEditor: require("#ckeditor/ckeditor5-react").CKEditor,
ClassicEditor: require("../ckeditor5/build/ckeditor"),// this is not working
};
setLoaded(true);
}, []); // run on mounting
if (loaded) {
return (
<CKEditor
editor={ClassicEditor}
data="<p>Hello from CKEditor 5!</p>"
/>
);
} else {
return <h2> Editor is loading </h2>;
}
}
export default Editor;
when i use custom build ckeditor it gives me error.
TypeError: a.clone is not a function
at Array.map (<anonymous>)
please help me integrate ckeditor5 custom build with nextjs. would be appreciated.

Related

Next.js: How to use useState and AuthContext without invalidating SSG html

I have an AuthContext to manage the authentication in my Next.js app. The _app.js file looks like this:
import '../styles/global.css'
import 'tailwindcss/tailwind.css'
import { AuthProvider } from '../components/AuthContext'
function MyApp({ Component, pageProps }) {
return (
<>
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
</>
)
}
export default MyApp
And the AuthContext file is something like this:
import React, { useContext, useState, useEffect } from "react"
import { auth, db } from "./Firebase";
import { doc, getDoc } from "firebase/firestore";
const AuthContext = React.createContext()
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState([])
const [loading, setLoading] = useState(true)
const [userData, setUserData] = useState({})
const [companyData, setCompanyData] = useState({})
useEffect(() => {
const unsubscribe =
auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
useEffect(() => {
const fetchData = async () => {
const qu = doc(db, "users", currentUser.uid)
const datau = await getDoc(qu)
setUserData(datau.data());
const qc = doc(db, "companies", currentUser.uid)
const datac = await getDoc(qc)
setCompanyData(datac.data());
}
currentUser?.uid && fetchData()
}, [currentUser])
const value = {
currentUser,
userData,
companyData
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
export function useAuth() {
return useContext(AuthContext)
}
Then I have a dynamic page [id].js that is something like this:
import { useAuth } from '../../components/AuthContext';
import Head from 'next/head';
export async function getStaticProps(context) {
// fetch and return data
}
export async function getStaticPaths() {
// fetch paths
return { paths, fallback: 'blocking' }
}
export default function Job(props) {
const { userData, currentUser } = useAuth();
const data = props.data;
return (
<>
<Head>
{data.title} | SiteName
</Head>
<h1>data.title</h1>
{currentUser ? userData.name : null}
</>
)
}
Problem: The website works perfectly, BUT when I check the page [id].js source code, Next.js doesn't build the HTML structure with head and body optimized for SEO (which is the main reason why I'm migrating to Next.js).
If I remove the "!loading &&" (see below) in the AuthContext file, the Next's SSG HTML generation works BUT the whole app starts to give me errors everywhere.
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
What exactly is the problem? And any idea on how to solve it?

Reference Error:Navigator not defined with nextjs

My code is like this:
import React, { useEffect } from 'react';
import alanBtn from '#alan-ai/alan-sdk-web';
const alanKey = my key;
const App = () => {
useEffect(() => {
alanBtn({
key: alanKey,
onCommand: ({ command }) => {
alert('This code was executed');
}
})
}, []);
return (
<div><h1>Alan AI News Application</h1></div>);
}
export default App;
But i am getting the error as:
Reference Error:Navigator not defined..
How to fix it?
Browser objects like window , navigator etc should be define in useEffect first before use.
const [pageURL, setPageURL] = useState("");
const [isNativeShare, setNativeShare] = useState(false);
useEffect(() => {
setPageURL(window.location.href);
if (navigator.share) {
setNativeShare(true);
}
}, []);
// Now, use can use pageURL , isNativeShare in code
This is not an issue with your Next.js code it's just the way you are supposed to call the alan-ai library.
Below is the solution that should work for you.
import React, { useEffect } from "react";
const alanKey = "my key";
function App() {
useEffect(() => {
const alanBtn = require("#alan-ai/alan-sdk-web");
alanBtn({
key: "myKey",
rootEl: document.getElementById("alan-btn")
});
}, []);
return (
<div>
<h1>Alan AI News Application</h1>
</div>
);
}
export default App;
Here is the discussion link for the same https://github.com/alan-ai/alan-sdk-web/issues/29#issuecomment-672242925.
Hope this solves your issue.
Happy Coding.

How to add firebase screen tracking analytics with React Native React Navigation when using createStackNavigator?

I have a React Native app and am using React Navigation. I am now trying to add screen tracking analytics with firebase.
I am following this documentation, which has this sample code:
import analytics from '#react-native-firebase/analytics';
import { NavigationContainer } from '#react-navigation/native';
<NavigationContainer
ref={navigationRef}
onStateChange={state => {
const previousRouteName = routeNameRef.current;
const currentRouteName = getActiveRouteName(state);
if (previousRouteName !== currentRouteName) {
analytics().setCurrentScreen(currentRouteName, currentRouteName);
}
In my code, however, I am creating my base NavigationContainer with a function like so:
export default createStackNavigator(
{
Home: MainTabNavigator,
SignIn: SignInNavigator,
},
{
transitionConfig: dynamicModalTransition,
headerMode: 'none',
initialRouteName: 'Home',
},
);
What is the best way to integrate the code from the example?
The problem is because you are on react-navigation v4.x.x, but the example you have is for v5.x.x.
In v4, event listeners can be added on AppContainer.
The example below is for v4.
import React from 'react';
import { createAppContainer, createStackNavigator } from 'react-navigation';
function getActiveRouteName(navigationState) {
if (!navigationState) {
return null;
}
const route = navigationState.routes[navigationState.index];
if (route.routes) {
return getActiveRouteName(route);
}
return route.routeName;
}
const nav = createStackNavigator({...});
const AppContainer = createAppContainer(nav);
export default () => {
return <AppContainer
onNavigationStateChange={(prevState, currentState, action) => {
const currentRouteName = getActiveRouteName(currentState);
const previousRouteName = getActiveRouteName(prevState);
if (previousRouteName !== currentRouteName) {
analytics().setCurrentScreen(currentRouteName, currentRouteName);
}
}}
/>
}
I'm using NavigationContainer and createStackNavigator, too and this is how I did it, like in the example for screen tracking at reactnavigation.org
import * as Analytics from 'expo-firebase-analytics';
import { useRef } from 'react';
import { NavigationContainer } from '#react-navigation/native';
export default () => {
const navigationRef = useRef();
const routeNameRef = useRef();
return (
<NavigationContainer
ref={navigationRef}
onReady={() =>
(routeNameRef.current = navigationRef.current.getCurrentRoute().name)
}
onStateChange={async () => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current.getCurrentRoute().name;
if (previousRouteName !== currentRouteName) {
// The line below uses the expo-firebase-analytics tracker
// https://docs.expo.io/versions/latest/sdk/firebase-analytics/
// Change this line to use another Mobile analytics SDK
await analytics().logScreenView({
screen_name: currentRouteName,
screen_class: currentRouteName
});
}
// Save the current route name for later comparison
routeNameRef.current = currentRouteName;
}}
>
{/* ... */}
</NavigationContainer>
);
};

Trying to subscribe to a collectionusing react-meteor-hooks but loading is always true

Trying to implement 'react-meteor-hooks, but 'loading' variable is always true:
import React from 'react';
import { useSubscription, useMongoFetch } from 'react-meteor-hooks';
import { Comments } from '../../../../collections/comments';
export const GiveComments = (props) => {
const loading = useSubscription('getComments');
if (loading) {
console.log('loading... ');
} else {
const allComments = useMongoFetch(Comments.find({}));
console.log('loaded: ', allComments);
}
return (null);
};
Publishing:
Meteor.publish('getComments', function() {
return Comments.find({});
});
These hooks looks amazing, but can't get it to work. Why 'loading' does not stop?

CSS import in React Component not working in Electron app

First of all, I want to say sorry because I feel like I lack some theorical background for this problem, but right now I am stuck so here I am.
I want to set up an Electron app with just the usual main.js entry point which handles BrowserWindow creation. I want to create multiple, different windows, so the boilerplates I found on the Internet are no good for me.
So, my main.js creates a window by using an .html file that uses a script tag to add its renderer, that just sets up a React component like this:
const React = require('react');
const ReactDOM = require("react-dom");
const ReactComponent = require('path/to/component').default;
window.onload = () => {
ReactDOM.render(<ReactComponent />, document.getElementById('my-component'));
};
My component is very basic so far:
import React from 'react';
import './ReactComponent.css';
class ReactComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="ReactComponent">
some text
</div>
);
}
}
export default ReactComponent;
And the .css is even simpler:
.ReactComponent {background-color: red;}
I used Gulp + Babel to compile my code, and everything works well until I add that
import './ReactComponent.css';
Which throws this error:
Uncaught SyntaxError: Unexpected token .
Reading the .css file.
Here is my .babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
And my gulpfile.js:
const spawn = require('child_process').spawn;
const gulp = require('gulp');
const maps = require('gulp-sourcemaps');
const babel = require('gulp-babel');
const css = require('gulp-css');
const path = require('path');
/* Build */
gulp.task('build-css', function () {
return gulp.src('src/**/*.css')
.pipe(maps.init())
.pipe(css())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/src'));
});
gulp.task('build-js', () => {
return gulp.src(['src/**/*.js', 'src/**/*.jsx', '!src/**/*.test.js'])
.pipe(maps.init())
.pipe(babel())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/src'));
});
gulp.task('build-main-js', () => {
return gulp.src('main.js')
.pipe(maps.init())
.pipe(babel())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/'));
});
gulp.task('build', gulp.series('build-css', 'build-js', 'build-main-js'));
/* Copy */
gulp.task('copy-html', () => {
return gulp.src('src/**/*.html')
.pipe(maps.init())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/src'));
});
gulp.task('copy-assets', () => {
return gulp.src('assets/**/*').pipe(gulp.dest('dist/assets'));
});
gulp.task('copy', gulp.parallel('copy-html', 'copy-assets'));
/* Execute */
const cmd = (name) => path.resolve(__dirname) + '\\node_modules\\.bin\\' + name + '.cmd';
const args = (more) => Array.isArray(more) ? ['.'].concat(more) : ['.'];
const exit = () => process.exit();
gulp.task('start', gulp.series('copy', 'build', () => {
return spawn(cmd('electron'), args(), { stdio: 'inherit' }).on('close', exit);
}));
gulp.task('release', gulp.series('copy', 'build', () => {
return spawn(cmd('electron-builder'), args(), { stdio: 'inherit' }).on('close', exit);
}));
gulp.task('test', gulp.series('copy', 'build', () => {
return spawn(cmd('jest'), args(), { stdio: 'inherit' }).on('close', exit);
}));
At this point I don't even know anymore what the problem is... Please send help!
Many thanks!

Resources