How to disable cache for specific pages dynamically in next js? - reactjs

I want some posts without caching and some posts with caching.
Each post has a property which tells whether the post should be cached or not e.g. post.cached. I am using getServerSideProps method to render posts.
next.config.js
async headers() {
return [
{
source: "/",
headers: [
{
key: "Cache-Control",
value: "public, max-age=300",
},
],
},
]
}

You have two options:
Inside getServerSideProps method of the pages you want to customize caching
Page.getServerSideProps = async ({ res }) => {
res.setHeader('Cache-Control', 'no-store');
return {
props: {}
};
};
Via next.config.js
module.exports = {
headers: () => [
{
// Create glob to target specific pages you want
source: '/:path*',
headers: [
{
key: 'Cache-Control',
value: 'no-store',
},
],
},
],
}

Related

Why doesn't my API work when I use info from an env file in my React app?

I have a React app where I access data from an API.
I works perfectly when I hard code all the info in my API function, but when I try to get it from an .env file, it does not work.
Below is the API code:
const [data, setDatas] = useState()
let myHeaders = new Headers();
const getDatas = async () => {
myHeaders.append("Access-Control-Request-Headers", process.env.REACT_APP_ACCESS_CONTROL);
myHeaders.append("Authorization", process.env.REACT_APP_BEARER);
const requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
try {
let response = await fetch(
process.env.REACT_APP_DATAS_API, requestOptions);
let result = await response.json();
setDatas(result)
} catch (err) { console.error(err); }
};
console.log(datas && Object.values(datas))
Below is what the .env file looks like:
REACT_APP_PROJECTS_API=https://this-is-the-api-uri
REACT_APP_ACCESS_CONTROL=this-is-the-access-control
REACT_APP_BEARER=Bearer this-is-the-bearer-token
And below is the contents of my gatsby-config.js file:
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
module.exports = {
siteMetadata: {
title: `Site Name`,
siteUrl: `https://www.yourdomain.tld`
},
plugins: ["gatsby-plugin-image", "gatsby-plugin-react-helmet", "gatsby-plugin-sitemap", {
resolve: 'gatsby-plugin-manifest',
options: {
"icon": "src/images/icon.png"
}
}, "gatsby-plugin-mdx", "gatsby-transformer-remark", "gatsby-plugin-sharp", "gatsby-transformer-sharp", {
resolve: 'gatsby-source-filesystem',
options: {
"name": "images",
"path": "./src/images/"
},
__key: "images"
}, {
resolve: 'gatsby-source-filesystem',
options: {
"name": "pages",
"path": "./src/pages/"
},
__key: "pages"
}]
};
Why doesn't it work with .env?
If you want your .env variables to be accessible on Gatsby's frontend, you need to prefix those variables with GATSBY_ prefix

Next.js redirect if there is no cookie

Is there a way to redirect the user from checkout to the join page ONLY if there is no cookie user_token. Next.js allows to set only strings and undefined as value, but I need to validate that there is no cookie:
redirects: async () => [
{
source: '/checkout',
has: [
{
type: 'cookie',
key: 'user_token',
value: '',
},
],
permanent: true,
destination: '/join',
},
],
I tried to use regex for empty string, but it did not work:
redirects: async () => [
{
source: '/checkout',
has: [
{
type: 'cookie',
key: 'user_token',
value: '(^$)',
},
],
permanent: true,
destination: '/join',
},
],
I think that the problem you have is, that you just limit it to an empty cookie.
You will have to check for the absence of a cookie inside the route and send a res.redirect from there (https://nextjs.org/docs/api-routes/response-helpers)
And: are you sure you want a permanent redirect?? The browser caches it and those users will be redirected without a request to the server in the future.

gatsby-remark-images-medium-zoom not working

I am creating a blog with Gatsbyjs.
The content is taken from contentful and the content type is markdown.
graphql is:
contentfulBlogPost(id: { eq: $id }) {
content {
childMdx {
body
}
}
}
The acquired body is passed to the following components.
const Markdown = ({ children }) => (
<div>
<MDXProvider>
<MDXRenderer>{children}</MDXRenderer>
</MDXProvider>
</div>
)
<Markdown>{data.contentfulBlogPost.content.childMdx.body}</Markdown>
gatsby-config is:
{
resolve: `gatsby-plugin-mdx`,
options: {
plugins: [
`gatsby-remark-images`,
`gatsby-remark-images-medium-zoom`
],
gatsbyRemarkPlugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 500,
linkImagesToOriginal: false,
},
},
{
resolve: `gatsby-remark-images-medium-zoom`,
options: {}
},
],
},
},
Medium-zoom does not work with this configuration.
Thank you in advance.

React/Electron not loading static files located in public directory

I've built a React app that works fine on Chrome. Now I wanted to convert it into an Electron app. The assets located in the /public directory (pictures, icons, JSON files) cannot be loaded in the electron app.
The browser console displays errors while loading these files:
Failed to load resource: net::ERR_FILE_NOT_FOUND.
When I insert an asset picture from the public directory directly in the generated index.html file like
<img src="pic.png" alt=" pic"/>
it works, but loading it the same way from react components doesn't work. The asset files are being loaded from the root (e.g. file://pic.png)
Here is the project structure:
package.json:
"homepage": "./",
"main": "src/electron-starter.js",
"build": {
"appId": "com.myapp",
"productName": "App",
"files": [
"build/**/*",
"src/electron-starter.js"
],
"directories": {
"buildResources": "public"
},
"win": {
"target": "NSIS"
},
"linux": {
"target": [
"AppImage",
"deb"
],
"category": "Audio"
},
"dmg": {
"contents": [
{
"x": 110,
"y": 150
},
{
"x": 240,
"y": 150,
"type": "link",
"path": "/Applications"
}
]
}
}
createWindow function inside electron-starter.js:
function createWindow () {
const mainWindow = new BrowserWindow({
width: 1200,
height: 700,
webPreferences: {
nodeIntegration: true
}
})
if (process.env.ELECTRON_START_URL) {
mainWindow.loadURL(process.env.ELECTRON_START_URL);
} else {
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, '../build/index.html'),
protocol: 'file',
slashes: true
}))
}
mainWindow.webContents.openDevTools()
}
Thank's in advance for your help!
It turns out that Electron doesn't use React's /public directory. So I moved the required assets into /src/assets and imported them directly inside the component classes. Example:
import logo from "../assets/logo.png";
class MyComponent extends React.Component {
render() {
<img src={logo} alt="my_logo"/>
}
}
I've also added <base href="./"/> to the header of the index.html file.
i have this example, and you charge an path with "../" this example if you can enter with path don't need include ".." i hope you can resolve
import { ipcMain, dialog } from 'electron'
import isImage from 'is-image'
import filesize from 'filesize'
import fs from 'fs'
import path from 'path'
function setMainIpc (win) {
ipcMain.on('open-directory', (event) => {
dialog.showOpenDialog(win, {
title: 'Select new location',
buttonLabel: 'open dir',
properties: ['openDirectory']
},
(dir) => {
if (dir) {
loadImages(event, dir[0])
}
})
})
ipcMain.on('load-directory', (event, dir) => {
loadImages(event, dir)
})
ipcMain.on('open-save-dialog', (event, ext) => {
dialog.showSaveDialog(win, {
title: 'save image modify',
buttonLabel: 'save imagen',
filters: [{name: 'Images', extensions: [ext.substr(1)]}]
}, (file) => {
if (file) {
event.sender.send('save-image', file)
}
})
})
ipcMain.on('show-dialog', (event, info) => {
dialog.showMessageBox(win, {
type: info.type,
title: info.title,
message: info.message
})
})
}
function loadImages (event, dir) {
const images = []
fs.readdir(dir, (err, files) => {
if (err) throw err
for (var i = 0, length1 = files.length; i < length1; i++) {
if (isImage(files[i])) {
let imageFile = path.join(dir, files[i])
let stats = fs.statSync(imageFile)
let size = filesize(stats.size, {round: 0})
images.push({filename: files[i], src: `plp://${imageFile}`, size: size})
}
}
event.sender.send('load-images', dir, images)
})
}
module.exports = setMainIpc

path.resolve() was not pointing the templates/blogpost.js in gatsby application

I'm developing very basic blog application that display blog posts from markdown files. When i click each post, it will open on the new route with dynamically create page with createPages functionality. The problem is When i pointing the templates/blogpost.js in the gatsby-node.js.
It is showing like this.
Your site's "gatsby-node.js" created a page with a component that doesn't exist.
Error :
The path to the missing component is "C:\Users\viper\Desktop\react\gatsby\portfolio\imlohith\src\templates\blog.js"
The page object passed to createPage:
{
"path": "/post-four",
"component": "C:\\Users\\viper\\Desktop\\react\\gatsby\\portfolio\\imlohith\\src\\templates\\blog.js"
}
const postTemplate = path.resolve(`src/templates/blog.js`)
return graphql(`
{
allMarkdownRemark {
edges {
node {
html
id
frontmatter {
path
title
date
author
}
}
}
}
}
`).then(res => {
if (res.errors) {
return Promise.reject(res.errors)
}
res.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.path,
component: postTemplate,
})
})
})
}
Gatsby-congig.js file
const config = require('./config');
module.exports = {
pathPrefix: config.pathPrefix,
siteMetadata: {
title: config.siteTitle,
description: "This is awesome site awesome awesome"
},
plugins: [
'gatsby-plugin-react-helmet',
'gatsby-plugin-catch-links',
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/pages`,
name: 'pages',
},
},
'gatsby-transformer-remark',
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: config.manifestName,
short_name: config.manifestShortName,
start_url: config.pathPrefix || config.manifestStartUrl,
background_color: config.manifestBackgroundColor,
theme_color: config.manifestThemeColor,
display: config.manifestDisplay,
icon: config.manifestIcon, // This path is relative to the root of the site.
},
},
'gatsby-plugin-sass',
'gatsby-plugin-offline',
],
};

Resources