I want to build a templating engine for user profiles. After picking a design, which might consist of HTML, CSS, and JS, I would like to be able to server-side/static render a users profile page using their chosen template.
I'm looking for a good place to start / for someone to point me in the right direction. Assuming there are templates already stored in a database, or saved as files to AWS, how might I dynamically load and render the template along with the users profile data using Next.js? What might be an optimal way of storing the templates?
Thank you,
Try use nextjs GetStaticProps or GetStaticPatch
https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props
https://nextjs.org/docs/basic-features/data-fetching/get-static-props
write this function in some NextPage file
export async function getStaticProps(context) {
//all logic done here will be rendered server-side.
return {
props: {}, // will be passed to the page component as props
}
}
It can consume a database within this layer, do not want to use an external API, in some projects I use the ORM Prisma to facilitate the process.
https://www.prisma.io/nextjs
// Fetch all posts (in /pages/index.tsx)
export async function getStaticProps() {
const prisma = new PrismaClient()
const posts = await prisma.post.findMany()
return {
props : { posts }
}
}
Related
I want to be able to redirect to another page in Next.js passing data. The reason about why I want to do it is the following:
I am working on a project in which the user can be an entity or not. If it is not an entity the page about the user will be / and if it is an entity the page about the user will be /entity.
When I go to the page / I use getServerSideProps to fetch all the data about the user and send it as a prop. However, if the fetched user is an entity I redirect to /entity. Then, I use getServerSideProps in /entity to fetch all the data about the user (that is an entity).
I am doing two requests when I only should do one of them. If I manage to redirect to /entity passing the data that I already fetched I wouldn't have this problem. Is there a way I can do it?
// index.js
export async function getServerSideProps(context) {
const user = await getUser(accessCookies(context));
if (user.isEntity)
return { redirect: { destination: "/entity", permanent: false } }; // Would like to send user
return { props: { user} };
}
I don't see any way to achieve it and I don't even know if it is possible.
might be question is duplicated ,even though my business case is little bit different since I need help from experts.
First time, I am using Micro frontend architecture in current project with help of single spa framework
with reactjs.
I have experience in reactjs with redux(thunk,saga) but in single spa, I am unable to intercept the provider with store in individual MFE root component.
anybody has used reactjs with Single SPA framework along with redux with individual MFE.
my all MFE are in reactjs only.
#reactjs #redux #redux-saga.
I have implemented in some time back, was using redux for inter app communication between MFEs as well.
Store was build separately in child app.
This store would be imported by the master app and registered in global event distributor in the master app.
class GlobalEventDistributor {
constructor() {
this.stores = [];
}
registerStore(store) {
this.stores.push(store);
}
dispatch(event) {
this.stores.forEach((s) => s.dispatch(event));
}
}
This GlobalEventDistributor along with the store will be passed as a custom prop while registering application.
let storeModule = {},
customProps = {
globalEventDistributor: globalEventDistributor,
...additionalProps,
};
try {
storeModule = storeURL
? await SystemJS.import(storeURL)
: { storeInstance: null };
} catch (e) {
console.error(`Could not load store of app ${name}.`, e);
}
if (storeModule.storeInstance && globalEventDistributor) {
// add a reference of the store to the customProps
customProps.store = storeModule.storeInstance;
// register the store with the globalEventDistributor
globalEventDistributor.registerStore(storeModule.storeInstance);
}
// register the app with singleSPA and pass a reference to the store of the app as well as a reference to the globalEventDistributor
singleSpa.registerApplication(
name,
() => SystemJS.import(appURL),
hashPrefix(hash, wild),
customProps
);
After passing as customer props store and GlobalEventDispatcher will be available in the rootComponent passed to singleSpaReact of child app. From rootComponent it will be passed as a prop to Provider
I have referred below repo while implementing it.
https://github.com/me-12/single-spa-portal-example
Note: Currently we have are migrating to Module Federation instead of using singleSPA you can try that too.
I have one quick and dirt question.
Is it possible to catch a query parameter from a server redirect inside of Gatsby.js application?
We have a Pardot tracking link that does redirect to our thank you page which is built in Gatsby.js and I want to pass some query parameters to the application it self from that redirect.
So for example:
www.trackedlink.com/thank-you?programme_code=CODE_FROM_REDIRECT_ON_SERVERSIDE
will redirect to:
www.gatsbyapplicationthatwillreadthequery.com/thank-you?programme_code=CODE_FROM_REDIRECT_ON_SERVERSIDE
Is it possible to read that query inside of the application if it's coming from the outside of the app?
Cheers and have a great week!
If they are triggered in the client-side the redirection will be caught by the application and yes, it would possible if they are coming from outside the app or using a standard anchor. Not using a #reach/router (<Link> component since it's a limitation).
A clean and scalable way to use it is by adding in the function in your gatsby-browser.js configuration:
import React from 'react';
import { checkUrlFunction } from './src/services/yourCheckUrlFunction';
export const onClientEntry = () => checkUrlFunction();
Adding a function in gatsby-browser.js with onClientEntry API will trigger your function once the page is loaded. From the documentation:
onClientEntry Function (_: emptyArg, pluginOptions: pluginOptions) => undefined Called when the Gatsby browser runtime first starts.
Your function should look like:
export const checkUrlFunction = () => {
if (typeof window !== 'undefined') {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const programmeCode= urlParams.get('programme_code')
if(programmeCode) window.localStorage.setItem('programmeCode', programmeCode)
console.log(programmeCode); // will output CODE_FROM_REDIRECT_ON_SERVERSIDE
};
};
Note the typeof window !== 'undefined' necessary to avoid issues if the window object is not defined when triggering the function
Hi Ferran, thank you for your solution but unfortunately, it does not
work when the redirect happens. It only works if the query string is
inside of the application
Yes, the idea of adding the function in gatsby-browser.js is to avoid the addition of checkUrlFunction() in each page, template, or component. The disadvantage is that you lose a bit of control but it saves a lot of overwriting code and improves the scalability and readability.
Thanks, Ferran, if you could show me an example of it - it would be
amazing! This cookie topic is sort of unknown water for me
So, with your specifications updated, I've added the localStorage approach since it's easier to achieve in a non-IDE environment like this, but the idea is exactly the same.
Set a vault (cookie or localStorage) automated in the gatsby-browser.js function
if(programmeCode) window.localStorage.setItem('programmeCode', programmeCode)
This sets a localStorage key/value pair ('programmeCode' (key)/programmeCode (value)
Access to that vault in your component. Use a componentDidMount lifecycle or useEffect hook to ensure that is loaded before the DOM tree is mounted.
useEffect(()=>{
if(typeof window !== undefined) console.log(window.location.getItem('programmeCode')
}, [])
I am learning React and want to create an application with Symfony4 as my backend and React frontend. I am stuck now when I need to pass some kind of data to the frontend from my backend. I don't really know what is the right way to do it? Following some tutorials I am doing it like this:
From the controller I send some data to the twig file:
/**
* #Route("/")
*/
public function homepage()
{
$date = new DateTime();
$curr_date = $date->format('Y-m-d H:i:s');
return $this->render('base.html.twig', [
'gameDate' => $curr_date
]);
}
In the twig file, I set it as a data-attribute
base.html.twig:
<div id="root" data-event-date="{{ gameDate }}">
Then I can get the variable as a dataset in my JavaScript
App.js:
const root = document.getElementById('root');
ReactDOM.render(<Homepage {...(root.dataset)}/>, root);
And render it from props.
Homepage.js:
class Homepage extends Component {
constructor(props) {
super(props)
this.state = {
prizePool: '',
gameDate: '',
numberOfPlayers: ''
}
}
onParticipateClick = (event) => {
this.setState({prizePool: Math.random()})
}
render()
{
return (
<div className="mt-c-10">
<GameInfoBox gameDate={this.props.eventDate}/>
</div>
)
}
}
This actually works, but I am concerned with showing all the information in data variables because anyone can see it. What if I want to pass user ID or something secret? There should be another way to do it right?
It depend on what you attemps, if you are working on big project, you can use API to serve backend data. Take a look here: https://www.modernjsforphpdevs.com/react-symfony-4-starter-repo/. There is a simple example.
But if you want something more use api-platform or FOSRestBundle.
"Best and safest" is a little ambiguous - do you need strict security, or safe as in code stability etc?
Instead of passing your data from controller to view (twig) and then into HTML elements or global, another way is this:
Controller loads the view file with your nav and other stuff
Controller loads React (however you do this, Webpack etc)
React calls another controller (i.e. fetch()). This controller is probably somewhere like src/Api/Controller/ as it wont render a view so keep it separate to the other controllers which do render a view
The API controller calls your DB or remote API (etc) and gets the data and sends it back as JsonResponse back to React.
React can then show the data, or an error message depending on the response status
The API controller in your MW can also handle errors and do some logging, so React just gets a 200 and the data or a 400 (or whatever) and it can show a nice message to the user as normal.
Where would I store the API URI centrally in a ReactJS Application? The URI only changes between environments and should be easily configurable (i.e. through environment variables).
I have looked into this package and into the new Context API, but am unsure it's the best way to achieve this. I have also looked into dotenv, but I don't like that I would have to use process.env.REACT_APP_SERVICE_URI in every component that wants to access the API. What is the usual approach?
I am not using Redux.
I don't think you need an external dependency to do that.
I usually create simple module called api-client.js, which is responsible for calls to external API and defining endpoints.
In your case you might have:
import axios from 'axios' // some http client lib
const endpoint = process.env.REACT_APP_SERVICE_URI? process.env.REACT_APP_SERVICE_URI : 'https://foo.api.net/'
export default {
getAllProducts () {
return axios.get(endpoint + 'products').then(response => {
log.debug(`api client fetched ${response.data.length} items`)
return response.data
}).catch(err => {
log.error(err.message)
throw err
})
}
},
getProductById (id) {
...
},
}
You read process.env.REACT_APP_SERVICE_URI only once.
I like to put this module inside api directory (and any other API related stuff).