Next build not building full html page with on demand SSG - javascript

I’m having an issue while using getStaticPaths and getStaticProps to have an on demand SSG for a sharing page. I'm using Next v12.1.0 and React 17.0.2.
When I build a particular /[id] page, I get the data but the HTML is not building as it should. Here's the code:
Code from page/[postId].tsx:
const PostShare: NextPage = ({ metadata }: any): JSX.Element => {
return (
<>
<Head>
<meta name="theme-color" content="#000000" />
<meta name="og:description" content="content shared via page" />
<meta name="og:title" content={metadata.title} />
<meta name="og:type" content={metadata.type} />
<meta name="og:image" content={metadata.image} />
<meta name="description" content="content shared via page" />
<title>Page | Share</title>
</Head>
<main className="min-h-screen min-w-screen bg-js-carta grid flex-col place-content-center">
<div className="flex flex-col justify-center items-center">
<div className="flex flex-col justify-center items-center mb-[2vh] md:mb-[3vh]">
<div className="relative w-[40vw] max-w-[380px] aspect-square mb-[20px] md:mb-[35px]">
<Image
src={"/assets/logo.svg"}
layout="fill"
alt={"log"}
/>
</div>
<h1 className="mb-[20px] md:mb-[35px] text-white font-semibold text-3xl">Redirection ...</h1>
<p className="mb-[35px] text-white w-[90vw] text-[14px] md:w-[38vw] text-center md:text-[17px] font-normal leading-9">Some text/p>
</div>
<div className="flex flex-col justify-between items-center w-[90%] md:w-[40vw] m-auto max-w-[435px]">
Some Link
<div className="w-full flex justify-between items-center mb-[20px] md:mb-[30px]">
<div className="h-[1px] bg-[#9894b5] w-[20%] md:w-[20%] lg:w-[28%]"></div>
<p className="text-center text-white text-[13px] font-normal md:text-[15px]">Some text</p>
<div className="h-[1px] bg-[#9894b5] w-[20%] md:w-[20%] lg:w-[28%]"></div>
</div>
Go
</div>
</div>
</main>
</>
);
};
export async function getStaticPaths() {
return {
paths: [{ params: { postId: '1' } }, { params: { postId: '2' } }],
fallback: 'blocking',
};
};
export async function getStaticProps({ params }) {
const postId: number = parseInt(params?.postId.toString());
const { data: metadata, error } = await getContentMetadataForShareRequest(postId);
return {
props: {
metadata,
},
};
};
This should create a new page once I request another id like I do on this test (this is an id of a post that I know of):
export async function getStaticPaths() {
return {
paths: [{ params: { postId: '4042' } }],
fallback: 'blocking',
};
};
export async function getStaticProps({ params }) {
const postId: number = parseInt(params?.postId.toString());
const { data: metadata, error } = await getContentMetadataForShareRequest(postId);
return {
props: {
metadata,
},
};
};
In here we can expect an html file called 4042.html to be created with all the data from the api, but somehow it's just building an almost empty html file:
Code from .next/server/pages/page/4042.html:
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="next-head-count" content="2" />
<link rel="preload" href="/_next/static/css/c9566ae84cfa64c1.css" as="style" />
<link rel="stylesheet" href="/_next/static/css/c9566ae84cfa64c1.css" data-n-g="" /><noscript data-n-css=""></noscript>
<script defer="" nomodule="" src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"></script>
<script src="/_next/static/chunks/webpack-eaae93af0b2e8468.js" defer=""></script>
<script src="/_next/static/chunks/framework-a070cbfff3c750c5.js" defer=""></script>
<script src="/_next/static/chunks/main-ef558cc4c27e2f83.js" defer=""></script>
<script src="/_next/static/chunks/pages/_app-2c36286d803ff756.js" defer=""></script>
<script src="/_next/static/chunks/pages/page/%5BpostId%5D-5c7db38fec69463d.js" defer=""></script>
<script src="/_next/static/9uNXtvnNpkvbdeI6xP2KX/_buildManifest.js" defer=""></script>
<script src="/_next/static/9uNXtvnNpkvbdeI6xP2KX/_ssgManifest.js" defer=""></script>
<script src="/_next/static/9uNXtvnNpkvbdeI6xP2KX/_middlewareManifest.js" defer=""></script>
</head>
<body>
<div id="__next" data-reactroot=""></div>
<script id="__NEXT_DATA__"
type="application/json">{"props":{"pageProps":{"metadata":{"id":4042,"title":"Des batteries presque éternelles à partir de déchets nucléaires !","type":"Multi (ex: article + vidéo)","url":"https://www.futura-sciences.com/tech/actualites/technologie-batteries-presque-eternelles-partir-dechets-nucleaires-65354/","image":"imageURlHiddenForObviousReasons","domain_name":"futura-sciences.com"}},"__N_SSG":true},"page":"/page/[postId]","query":{"postId":"4042"},"buildId":"someBuildId","isFallback":false,"gsp":true,"scriptLoader":[]}</script>
</body>
</html>
As you can see, I'm getting the needed data but it's not passed into the html as it should. Well, the page itself is basically empty when I build it.
I've tried everything and searched everywhere I could think of but nothing seems to be working.
If you guys have an idea of what could be the issue it would be super appreciated :)

In the end it was the Redux Persist gate causing the issue. I disabled it for that particular page and everything started working as expected.

Related

How do I make my index html file a vue app and still be able to host it on firebase?

So i've built a vue app with various different pages and a router index page and everything and I was viewing it locally and it looked good and everything was going good but when I went to go host it on firebase I can't figure out how to get my vue app file to show instead of the html one.
You will see that in the HTML the app and the main.js script are in the body of the HTML element.
<html>
<head>
<!-- update the version number as needed -->
<script defer src="/__/firebase/9.9.0/firebase-app-compat.js"></script>
<!-- include only the Firebase features as you need -->
<script defer src="/__/firebase/9.9.0/firebase-auth-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-database-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-firestore-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-functions-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-messaging-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-storage-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-analytics-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-remote-config-compat.js"></script>
<script defer src="/__/firebase/9.9.0/firebase-performance-compat.js"></script>
<!--
initialize the SDK after all desired features are loaded, set useEmulator to false
to avoid connecting the SDK to running emulators.
-->
<script defer src="/__/firebase/init.js?useEmulator=true"></script>
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8" />
<link rel="icon" href="/icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> Web page title</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<script>
document.addEventListener('DOMContentLoaded', function() {
const loadEl = document.querySelector('#load');
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
// // The Firebase SDK is initialized and available here!
//
// firebase.auth().onAuthStateChanged(user => { });
// firebase.database().ref('/path/to/ref').on('value', snapshot => { });
// firebase.firestore().doc('/foo/bar').get().then(() => { });
// firebase.functions().httpsCallable('yourFunction')().then(() => { });
// firebase.messaging().requestPermission().then(() => { });
// firebase.storage().ref('/path/to/ref').getDownloadURL().then(() => { });
// firebase.analytics(); // call to activate
// firebase.analytics().logEvent('tutorial_completed');
// firebase.performance(); // call to activate
//
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
try {
let app = firebase.app();
let features = [
'auth',
'database',
'firestore',
'functions',
'messaging',
'storage',
'analytics',
'remoteConfig',
'performance',
].filter(feature => typeof app[feature] === 'function');
loadEl.textContent = `Firebase SDK loaded with ${features.join(', ')}`;
} catch (e) {
console.error(e);
loadEl.textContent = 'Error loading the Firebase SDK, check the console.';
}
});
</script>
</html>
Aboves the html index file which I originally edited and below is a portion of the App page
<div>
<PopoverButton class="h-8 w-fit text-neutral-400 hover:text-red-800 active:text-red-900 font-bold cursor-pointer inline-flex align-middle p-1 m-4 transition ease-in-out duration-300"
>Locations</PopoverButton>
<PopoverPanel class="absolute z-10 bg-neutral-800 rounded-xl">
<div class="grid grid-cols-5">
<router-link to="/locations/Sydney">
<p class="h-8 w-fit m-4 text-neutral-400 hover:text-red-800 active:text-red-900 font-bold cursor-pointer transition ease-in-out duration-300"
>Sydney</p>
</router-link>
<router-view></router-view>
And below is my main.js
import { createApp } from 'vue'
import App from './App.vue'
import './style/index.css'
import router from '../src/router/index'
import { createPinia } from 'pinia'
import mongoose from 'mongoose'
createApp(App).use(router).use(createPinia()).mount('#app')
So basically what I'm trying to do is have it so that the actual vue app and the router-view inside it work again and put the vue app in the body of the index like it did before I hosted on firebase, if anyone has a way to fix this or a better way of doing this please let me know any help would be greatly appreciated, thanks.

Local undefined 404 when doing API call

This project is using the cocktail api to search for a specific ingredient (think gin or vodka) and then return all the drinks that contain the ingredient. I was able to get the results to display, but I wanted the thumbnail pic of the drink (included in the api as strDrinkThumb). When I try to get the pictures to display I get the follow error:
GET http://local/undefined 404 (Not Found)
window.addEventListener('DOMContentLoaded', (event) => {
console.log('DOM fully loaded and parsed');
});
let ingredients = document.getElementById('ingredients');
let searchTerm= document.getElementById('search-Bar');
let searchBtn = document.getElementById('searchBtn');
let drinkInfo = document.getElementById('drinkInfo');
let ingredientList = []
searchBtn.addEventListener("click", async (e) => {
const searchString = searchTerm.value.toLowerCase();
fetch(`https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=${searchString}`)
.then((response) => response.json())
.then((filteredIngredients) => {
displayIngredient(filteredIngredients.drinks);
})
.catch((error) => {
});
});
function displayIngredient(drinkData){
const ingredients = [];
//maps over array and makes new array
drinkInfo.innerHTML = drinkData.map( ({strDrink}) => { //destructuring
//use backticks and html
return` <div> //use backticks and html
<div class="card" style="width: 14rem;">
<div class="card-body">
<h5 class="card-title">${strDrink} </h5>
<img src="${drinkData.strDrinkThumb}"/>
</div></div>
`; //use backticks and html
}).join('');
drinkInfo.appendChild(drinkInfo);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cocktail App</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<input type="text" id="search-Bar" placeholder="Enter main ingredient..."/>
<button id="searchBtn">search</button>
</header>
<div class="drinkInfo" id="drinkInfo">
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<script type="text/javascript" src="./extrafile.js"></script>
</body>
</html>
In drinkData.map function you are only pulling strDrink value from the object, you need also get strDrinkThumb
Then you are trying get strDrinkThumb from drinkData which is an array, not an object.
Try this:
drinkInfo.innerHTML = drinkData.map( ({strDrink, strDrinkThumb}) => { //destructuring
//use backticks and html
return` <div> //use backticks and html
<div class="card" style="width: 14rem;">
<div class="card-body">
<h5 class="card-title">${strDrink} </h5>
<img src="${strDrinkThumb}"/>
</div></div>
`; //use backticks and html
}).join('');

firebase.database is not a function reactjs

I am new in firebase I am making a simple profile with User information and I want to edit and store the data in the dp in the firebase
first I added the CDN this is my index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Level Up Elearning</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
<script src="/__/firebase/8.5.0/firebase-app.js"></script>
<script src="/__/firebase/8.5.0/firebase-analytics.js"></script>
<script src="/__/firebase/init.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase-database.js"></script>
</body>
</html>
I tried all these scripts
and this is my firebase file
import firebase from "firebase/app";
var firebaseConfig = {...};
let fireDb = firebase.initializeApp(firebaseConfig);
export default fireDb.database().ref();
and this is where I call it
import React from "react";
import UserForm from "./UserForm";
import firebaseDb from "../firebase.js";
const UserProfile = () => {
const AddOrEdit = (obj) => {
firebaseDb.child("contacts").push(obj, (err) => {
if (err) {
console.log(err);
}
});
};
return (
<>
<div class="container py-4">
<div class="p-5 mb-4 bg-light rounded-3">
<div class="container-fluid py-5">
<h1 class="display-10 fw-bold">Profile Page</h1>
</div>
</div>
<div class="row align-items-md-stretch">
<div class="col-md-6">
<div class="h-100 p-5 text-white bg-dark rounded-3"></div>
</div>
<div class="col-md-6">
<div class="h-100 p-5 bg-light border rounded-3">
<UserForm AddOrEdit={AddOrEdit} /> // here I send the function as props to user form
</div>
</div>
</div>
</div>
</>
);
};
export default UserProfile;
this is a pic for the error
You're only importing firebase/app, which means the Realtime Database is not available in your code your.
to fix that, add:
import "firebase/database";
This then makes firebase.database() available as a side-effect.

How to style date generated by GET request and received in JSON format?

I am trying to style the data which I am receiving from a GET request. The api is returning JSON format but I am not sure how to get started with the styling. My code looks like this: **Index.html file:**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://unpkg.com/tailwindcss#1.9.6/dist/tailwind.min.css">
</head>
<body>
<div class="h-screen w-screen bg-gray-200 flex flex-col items-center justify-center">
<div class="w-1/2 bg-white shadow-2xl rounded">
<div class="bg-gray-700 rounded-t p-4">
<p class="text-white">
<span class="font-bold">GET</span>
Fixtures by date - Includes:
<span>localTeam</span>
<span>visitorTeam</span>
<span>Events</span>
</p>
</div>
<div class="bg-gray-200 p-4">
<p>Response of GET in JSON format</p>
</div>
<div style="height: 500px; overflow-y: scroll;">
<div class="p-4">
<pre id="content"></pre>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
and my script.js file
let request = new XMLHttpRequest();
let api_token = "my_api_token";
let includes = "&include=localTeam,visitorTeam,events";
let url = "https://soccer.sportmonks.com/api/v2.0/fixtures/date/2019-02-02?api_token=" + api_token + includes;
request.open('GET', url, true);
request.onload = function() {
let response = JSON.parse(this.response);
console.log(response.data);
const content = document.getElementById('content');
content.textContent = JSON.stringify(response.data, null, " ");
}
request.send();
Essentially all my data will be in a table format with date of the event, the two football teams next to each other and the final result of the match. I am trying to style the output data, unfortunately there is no much information in the documentation and I am not sure from where to start. Any help will be much appreciated.

ReadSpeaker webReader with React

i try to add readspeaker webreader to my project in React. Working but only when push to edit options and pulse button play. When he read options and close, play again in webapp page and read OK. I send email to support im waiting for reply and adding the solution here...
For websites that heavily use JS to build the website client-side, the solution is to add general: { usePost: true }. That will send the whole loaded website in base64 to Readspeaker servers instead of just sending the URL that needs to be read.
Example:
public/index.html:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
</head>
<body>
<noscript>
You Need JS
</noscript>
<div id="root"></div>
<script>
window.rsConf = {
params: `//cdn1.readspeaker.com/script/${ID_CUSTOMER}/webReader/webReader.js?pids=wr`,
general: { usePost: true }
};
</script>
</body>
</html>
important: window.rsConf
Component .jsx
import React, { useEffect } from "react";
import { Container } from "reactstrap";
const ReadSpeakerReader = () => {
useEffect(() => {
var oHead = document.getElementsByTagName('HEAD').item(0);
var oScript= document.createElement("script");
oScript.type = "text/javascript";
oScript.src=`//cdn1.readspeaker.com/script/${ID_USER}/webReader/webReader.js`;
oHead.appendChild(oScript);
}, [])
return (
<React.Fragment>
<section className="readspeaker-button-section mt-3 mb-2">
<Container>
<div id="readspeaker_button1" className="rs_skip rsbtn">
<a rel="nofollow"
className="rsbtn_play"
accessKey="L"
title="Escucha esta página utilizando ReadSpeaker webReader"
href={`//app-na.readspeaker.com/cgi-bin/rsent?customerid=${ID_CUSTOMER}&lang=es_co&readid=main-content-privateBCI&url=${encodeURIComponent( document.location.href )}`}
>
<span className="rsbtn_left rsimg rspart">
<span className="rsbtn_text">
<span>Escuchar</span>
</span>
</span>
<span className="rsbtn_right rsimg rsplay rspart"></span>
</a>
</div>
</Container>
</section>
</React.Fragment>
)
}
export default ReadSpeakerReader
With this your readspeaker webreader working well when your component is mounted in DOM

Categories