I am using Gastbyjs with Disqus plugin for commenting function. I followed the instruction here
I received emails about comments in my blog, but when I clicked the button "Reply to XXX" it opens.
https://localhost:8000/blogs/article-name
I think I missed some configuration for this.
Update 1
Here is the code where I use the config:
export const BlogPostTemplate = ({
content,
contentComponent,
description,
tags,
title,
helmet,
}) => {
const PostContent = contentComponent || Content;
const disqusConfig = {
shortname: process.env.GATSBY_DISQUS_NAME,
config: { identifier: title },
};
Update 2
I managed to use Reach/Router to access Location
I installed reach/router and I updated my code:
import { Location } from "#reach/router";
export const BlogPostTemplate = ({
content,
contentComponent,
description,
tags,
title,
helmet,
location
}) => {
const PostContent = contentComponent || Content;
console.log('--------------location---------');
console.log(location);
const disqusConfig = {
url: location.href,
shortname: process.env.GATSBY_DISQUS_NAME,
config: { identifier: title },
};
return (
<section className="section">
{helmet || ""}
<div className="container content">
<div className="columns">
<div className="column is-10 is-offset-1">
<h1 className="title is-size-2 has-text-weight-bold is-bold-light">
{title}
</h1>
<p>{description}Cool</p>
<PostContent content={content} />
{tags && tags.length ? (
<div style={{ marginTop: `4rem` }}>
<h4>Tags</h4>
<ul className="taglist">
{tags.map((tag) => (
<li key={tag + `tag`}>
<Link to={`/tags/${kebabCase(tag)}/`}>{tag}</Link>
</li>
))}
</ul>
</div>
) : null}
<DiscussionEmbed {...disqusConfig} />
</div>
</div>
</div>
</section>
);
};
const BlogPost = ({ data }) => {
const { markdownRemark: post } = data;
return (
<Layout>
<Location>
{({ location }) => (
<BlogPostTemplate
content={post.html}
contentComponent={HTMLContent}
description={post.frontmatter.description}
helmet={
<Helmet titleTemplate="%s | Blog">
<title>{`${post.frontmatter.title}`}</title>
<meta
name="description"
content={`${post.frontmatter.description}`}
/>
</Helmet>
}
tags={post.frontmatter.tags}
title={post.frontmatter.title}
location={location}
/>
)}
</Location>
</Layout>
);
};
However, when someone left a comment and I click the "Reply to {somebody}" button in the notification email, it still opens the localhost, rather than the real website link.
I finally figured it out. I'd like to break the answer into 4 parts:
How does the localhost url sneak into the comment's url?
The localhost url sneaked into the comment's url when I was commenting my article in a localhost development environment.
So to prevent this from happening again, only posting a comment in the production environment. If you did it in localhost environment, how to fix it? Please look at point 3.
What does localhost url is called?
The comment url is called Discussion Url.
Why do we need to know it?
Because this will be the key words for searching any related questions/answers. Without knowing this, I have wasted days for searching this configuration in Disqus.
So in short, it saves you tremendous time.
How and where to solve it?
As you can see there, the 2nd blog Link was using localhost, after I updated to the real website url, the problem was solved.
Hope my answer is helpful.
You need to pass the url to the disqusConfig of the current page disqus is located. In Gatsby, you can expect the location prop to be available to you on every page thanks to its use of #reach/router.
In your component:
import {Disqus} from "gatsby-plugin-disqus";
const Article = (props) => {
let disqusConfig = {
url: props.location.href,
identifier: props.your.identifier.source,
title: props.your.title.source,
};
return (
<div className="article">
<h1>Article title</h1>
<div>Article text</div>
<Disqus config={disqusConfig} />
</div>
)
}
Plugin config:
{
resolve: `gatsby-plugin-disqus`,
options: {
shortname: `your-short-name`
}
}
Note: you can't use something like window.location because there is no window during build time (there is no browser server side).
Related
I am using react and doing my portfolio
when people click on the button to view my github repo or project it goes to the wrong place
const Project = () => {
return (
<div className='work-container'>
<h1 className='project-heading'>Projects</h1>
<div className='project-container'>
{ProjectData.map((val, ind) => {
return (
<ProjectCard
key={ind}
imagesource={val.imagesource}
title={val.title}
text={val.text}
view={val.view}
github={val.github}
/>
)
})}
</div>
</div>
)
}
this is what my data file contains
const ProjectData = [
{
imagesource: project1,
title: 'Diamond Devs Tech Blog',
text: 'A community of developers who can write blogs about code or ask questions Built out of a need for developers have a nice simple platform rather than the complex ones out there in the marketplace, this was for an assignment foor my Bootcamp was challenging as had to do the front and backend from scratch using tech that I am still getting used too.',
view: 'https://diamond-developers-tech-blog.herokuapp.com/',
github: 'https://github.com/breakfireaus/diamond-developers-tech-blog',
},
]
export default ProjectData
I tried the above and instead of going to view project or github it goes to for example
https://matthew-younger-portfolio.herokuapp.com/portfolio/https://diamond-developers-tech-blog.herokuapp.com/
instead of just
https://diamond-developers-tech-blog.herokuapp.com/
I have reviewed code from you github repo. What you are doing is using React router NavLink to move to an external website which you cannot do as you can use it move within your application Documentation
.
You can convert them to a tag in your Project Card and they will work fine. You can use target="_blank" if you want to open the link in new tab.
import "./ProjectCardStyle.css";
import React from "react";
import { Link } from "react-router-dom";
const ProjectCard = (props) => {
return (
<div className="project-card">
<img src={props.imagesource} alt="Project Imagery" />
<h2 className="project-title">{props.title}</h2>
<div className="project-details">
<p>{props.text}</p>
<div className="project-buttons">
<a target={"_blank"} href={props.view} className="btn">
VIEW
</a>
<a target={"_blank"} href={props.github} className="btn">
Github
</a>
</div>
</div>
</div>
);
};
export default ProjectCard;
I created a project using NextJS template Blog starter kit, found here: https://vercel.com/templates/next.js/blog-starter-kit
I've successfully fetched my own posts from a graphql-endpoint and can render them, but when I add values to the post object on my own that weren't included in the original NextJS-project and pass them down to child components, they are available at first but then go undefined and throw an error if I try to use those values.
Please see below code and screenshot of how the values goes from defined to undefined.
I'm new to both Typescript and NextJS but have used React for some time, but I can't grasp why this happens. The code below renders, but I'd like to understand why just some of the props goes undefined, after clearly being included. Also in this specific example I'd like to be able to use coverImage.width in the Image component width-property instead of hardcoding a value.
index.tsx
type Props = {
allPosts: Post[]
}
export default function Index({ allPosts }: Props) {
const heroPost = allPosts[0]
const morePosts = allPosts.slice(1)
return (
<>
<Layout>
<Head>
<title>SWG - Blog</title>
</Head>
<Container>
<Intro />
{heroPost && (
<HeroPost heroPost={heroPost} />
)}
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
</Container>
</Layout>
</>
)
}
export const getStaticProps = async () => {
const allPosts = (await getPosts()) || [];
return {
props: { allPosts },
}
}
hero-post.tsx. All heroPost-prop values are available here. Please see below image of console print as well (image link until I have 10 points on SO).
type Props = {
heroPost: {
title: string
coverImage: {
url: string
width: number
height: number
}
date: string
excerpt: string
author: Author
slug: string
}
}
const HeroPost = ({ heroPost }: Props) => {
return (
<section>
<div className="mb-8 md:mb-16">
<CoverImage title={heroPost.title} src={heroPost.coverImage.url} slug={heroPost.slug} coverImage={heroPost.coverImage} />
</div>
<div className="md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28">
<div>
<h3 className="mb-4 text-4xl lg:text-5xl leading-tight">
<Link as={`/posts/${heroPost.slug}`} href="/posts/[slug]">
<a className="hover:underline">{heroPost.title}</a>
</Link>
</h3>
<div className="mb-4 md:mb-0 text-lg">
<DateFormatter dateString={heroPost.date} />
</div>
</div>
<div>
<p className="text-lg leading-relaxed mb-4">{heroPost.excerpt}</p>
<Avatar name={heroPost.author.name} picture={heroPost.author.picture} />
</div>
</div>
</section>
)
}
export default HeroPost
cover-image.tsx. Here's where the props of heroPost goes missing, but only the ones I've declared. Not "src" for example.
type Props = {
title: string
src: string
slug?: string
coverImage: {
url: string
width: number
height: number
}
}
const CoverImage = ({ title, src, slug, coverImage }: Props) => {
console.log(src);
//console.log(title);
console.log(coverImage);
const image = (
<>
<Image src={src} width={1495} height={841} />
</>
)
return (
<div className="sm:mx-0">
{slug ? (
<Link as={`/posts/${slug}`} href="/posts/[slug]">
<a aria-label={title}>{image}</a>
</Link>
) : (
image
)}
</div>
)
}
export default CoverImage
Apparently I can't post images since I'm a new member, but the above console.logs prints like this:
coverImage object exists
prop.src = correct src.value
props.coverImage = cover-image.tsx?0fdc:19 full coverImage object printed
Don't know where these react-devtools-backend lines come from but same thing here, both values exist.
react_devtools_backend.js:4082 correct src.value
react_devtools_backend.js:4082 full coverImage object printed
coverImage then goes undefined
cover-image.tsx?0fdc:19 undefined
but src in props still return its value
cover-image.tsx?0fdc:17 correct src.value
cover-image.tsx?0fdc:19 undefined
same thing with the lines from react_devtools_backend:
react_devtools_backend.js:4082 correct src.value
react_devtools_backend.js:4082 undefined
I've read numerous SO-threads and looked through the NextJS-docs but fail to realise what I'm doing wrong.
console.log of heroPost-object in hero-post component.
Everything works fine in development mode. At first look app is identical in build mode (I am using express for server side). But when I try to refresh my page (url contains params) I receive
only
{
surveyString: "[{"type":"radiogroup","name":"Favorite Character?","title":"Favorite Character?","isRequired":true,"colCount":1,"choices":["Walt","Hank","Jesse","Mike"]},{"type":"radiogroup","name":"Favorite Actor?","title":"Favorite Actor?","isRequired":true,"colCount":1,"choices":["Aaron Paul","Bryan Cranston","Jonathan Banks"]}]",
surveyTitle: "Breaking Bad Survey"
}
which is response send from server, which of course i want, but somehow app doesn't incorporate it.
Error which i receive in Chrome is
Not allowed to load local resource: view-source
In Firefox error looks somehow different
Content Security Policy: The page’s settings blocked the loading of a resource a ...resource link...
Through these errors I acknowledged about Content Security Policy, some basic method how express package works to overcome it and so on... But that is different story and I hope I will solve problem on react side.
I am optimist because I have identical behavior from a href links on other page. When I replace aHref with LinkTo app works as excepted.
I click on link and on a new page everything is ok, until I make refresh.
link is to github page:
component which not survives refresh
function SingleSurvey(props) {
const [complete, setComplete] = useState(false);
const [voted, setVoted] = useState(false);
const [json, setJson] = useState({});
const [title, setTitle] = useState("");
const [resultsDisplay, setResultsDisplay] = useState(false);
const { id } = useParams();
useEffect(() => {
surveyServices.getSingle(id).then((res) => {
const stringQuestions = JSON.parse(res.surveyString);
setJson({ questions: stringQuestions });
setTitle(res.surveyTitle);
});
}, [id]);
useEffect(() => {
const checkItem = window.localStorage.getItem(`chartVoted-${id}`);
if (checkItem) {
setVoted(true);
}
// eslint-disable-next-line
}, []);
function onComplete(result) {
surveyServices.updateVotes({
data: result.data,
id,
});
window.localStorage.setItem(`chartVoted-${id}`, true);
setComplete(true);
setTimeout(() => {
window.location.reload();
}, 1100);
}
return (
<main className="survey-page">
{complete && <p className="survey-finished"></p>}
{!voted ? (
<>
<Survey.Survey
json={json}
showCompletePage={false}
onComplete={(result) => onComplete(result)}
/>
<div className="show-results">
<button
className="btn-results"
onClick={() => setResultsDisplay(!resultsDisplay)}
>
{resultsDisplay ? "Hide Charts" : "Show Charts"}
</button>
<div
className="visible-results"
style={{ display: resultsDisplay ? "" : "none" }}
>
<Result id={id} title={title} />
</div>
</div>
</>
) : (
<div className="just-results">
<Result id={id} title={title} />
</div>
)}
</main>
);
}
export default SingleSurvey;
switch routes settings
<Router>
<Notification />
<Switch>
<Route exact path="/api/survey/single/:id" component={SingleSurvey} />
</Switch>
</Router>
ReactDOM render, I am using basic redux
<Provider store={store}>
<App />
</Provider>,
express
app.use(express.static(path.join(__dirname, "build")));
app.use("/api/survey", surveyController);
app.use("/api/users", usersController);
app.use("/api/login", loginController);
app.get("/", function (req, res) {
app.get("/*", function (req, res) {
res.sendFile(path.join(__dirname, "build", "index.html"));
});
});
If you want to see directly problem app is uploaded on heroku.
I hope I don't miss any valuable information. Anyone has idea how to fix unbelievably annoying problem?
You have confused and consequently overloaded your API routes and your client side routes.
When web browsers go to a website they are making GET requests, exactly the same as how you interact with your express server.
Your issue here is you are accidentally making a get request to your server by redirecting your users to your server endpoint which makes a GET request to your server.
What is happening
Url change triggered by a Link component (not in the code you've provided
React Router matches the URL without triggering an API request (this is how single page web app work)
<Route exact path="/api/survey/single/:id" component={SingleSurvey} />
On page refresh Express matches the URL and returns the API response instead of the index.html
app.use("/api/survey", surveyController);
Solution
Change your client-side paths to something like: /client/survey
Following Alex Mckay's answer I change route location
<Route
exact
path="/client/survey/single/:id"
component={SingleSurvey}
/>
And than fix content security policy error on my server side.
It is whole new area for me so I follow errors in my console and fix it one by one.
It is highly intuitive process with [helmet-csp] package.
app.use(
csp({
directives: {
defaultSrc: ["'self'"],
fontSrc: ["https://fonts.googleapis.com/", "https://fonts.gstatic.com"],
connectSrc: ["'self'", "http://localhost:3005"],
styleSrc: [
"'self'",
"'unsafe-inline'",
"https://surveyjs.azureedge.net/1.8.0/modern.css",
"https://fonts.googleapis.com",
"'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='",
"'sha256-OTeu7NEHDo6qutIWo0F2TmYrDhsKWCzrUgGoxxHGJ8o='",
],
imgSrc: ["'self'", "http://localhost:3005"],
scriptSrc: [
"'self'",
"unsafe-inline",
"'sha256-eE1k/Cs1U0Li9/ihPPQ7jKIGDvR8fYw65VJw+txfifw='",
],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
reportOnly: false,
})
);
Also I removed inline style from one of my component because component behaved strange
<>
<Survey.Survey
json={json}
showCompletePage={false}
onComplete={(result) => onComplete(result)}
/>
<div className="show-results">
<button
className="btn-results"
onClick={() => setResultsDisplay(!resultsDisplay)}
>
{resultsDisplay ? "Hide Charts" : "Show Charts"}
</button>
{resultsDisplay && (
<div>
<Result id={id} title={title} />
</div>
)}
</div>
</>
And it works.
Question: How can I use different URLs from different components in a third component as one ?
I am learning React.js and I would like to make multiple pages. This is an example project for learning purposes. There is one page where I can see the images and info of TeamA and there is another page where I can see the images and info of TeamB.
In order to avoid duplicates, I want to separate small components. I have a Card component which displays the image of team members with name and info. I want to use this one Card component for the page TeamA and also for the page TeamB.
The only difference now is the URL for the images - there is 1 URL for TeamA and one for TeamB. It should change accordingly.
I hope I could describe the problem. Please see the code examples below.
I appreciate your help. Have a nice day!
1st Component which has a unique URL for images:
const TeamA = ({id}) => {
const exampleImages = `https://url`;
return (
<div>
<Teams>
<Card teamImg={exampleImages}/>
</Teams>
</div>
);
}
2nd Component which also has a unique URL for images:
const TeamB = ({id}) => {
const exampleImagesB = `https://url`;
return (
<div>
<Teams>
<Card teamImg={exampleImagesB}/>
</Teams>
</div>
);
}
The Component that displays the information of the Team component (above). In this component, I want to use the URLs from the other components and add it to the img tag.
const Card = ({ name, email, id, teamImg }) => {
return (
<div className='tc'>
<img alt='image' src={`${teamImg}`}/>
<div>
<h2>{name}</h2>
<p>{info}</p>
</div>
</div>
);
}
You can make team a functional component of it's own:
const Team = ({id, imageUrl}) => {
return (
<div>
<Teams>
<Card teamImg={imageUrl}/>
</Teams>
</div>
);
}
Then you can pass imageUrl into your teams at a higher level without writing them out as separate components each time.
For example if you have your different urls as an array, this could be the component above team:
const AllTeams = () => {
const images = [{ id: 1, url: 'url1' }, { id: 2, url: 'url2' }];
return (
<>
{ images.map(image => <Team key={image.id} imageUrl={image.url} />) }
</>
);
}
I am learning GatsbyJS/React and am pretty new to coding as a whole. I am utilizing a starter gatsbyjs/React template to assist my learning.
I am just trying to add an additional navigation link on the page which links to an external website, not an internal page. As the site is written now, the navbar is a stateless function component? (I think) and I can add links to internal pages no problem, but because it puts the website URL before the link I end up with the website URL in front of every navlink I add. The navigation file is a jsx file.
Any help would be appreciated so I can learn.
I tried implementing GATSBYLINK but was unable to get it to implement properly.
Here is a portion of the nav code from the jsx file:
const ListLink = (props) => (
<li className="c-main-nav__elem" >
<Link
to={props.to}
className="c-main-nav__link"
activeClassName="c-main-nav__link--is-active"
exact={true}
onClick={props.closeMenu}
>
{props.children}
</Link>
</li>
);
class MainNav extends React.Component {
constructor(props) {
super(props);
this.toggleMenu = this.toggleMenu.bind(this);
this.closeMenu = this.closeMenu.bind(this);
this.state = {
links: [
{ to: '/', text: 'Home', icon: FaMapMarker },
{ to: '/toolbox/', text: 'Toolbox', icon: FaWrench },
{ to: '/playground/', text: 'Playground', icon: FaPaperPlaneO },
{ to: '/contact/', text: 'Contact', icon: FaEnvelopeO }
],
mainNavModifierClassName: '',
mobileDetailsNav: null
}
}
You can use html a tag to redirect to external urls
URLNAME
Or you can use window.location ="mywebsite.com"
Please find change the render method of the MainNav.js file as specifed below to achieve as specified in the image
render() {
return (
<div>
<ul className={ `c-main-nav ${this.state.mainNavModifierClassName}` }>
{
this.state.links.map((link, i) => (
<ListLink to={link.to} key={i} testLink={this.testLink}>
<link.icon />
<span className="c-main-nav__text">{link.text}</span>
</ListLink>
))
}
<FaMapMarker /><span>asdasdads</span>
<li
className="c-main-nav__elem c-main-nav__elem--close-link"
onClick={this.toggleMenu}
>
<a href="#" className="c-main-nav__link">
{ (this.state.mainNavModifierClassName) ? <FaChevronUp /> : <FaChevronDown /> }
<span className="c-main-nav__text">Close</span>
</a>
</li>
</ul>
{ this.state.mobileDetailsNav }
</div>
)
}
};
I have use google.com as my external url and asdasdasd as my link name please change it as per your requirement
Thankyou and wish you a good luck
Just add https / http before the domain name in href tag.
<a href={\`https://${hostname}\`\} target="_blank" rel="norefferer" >{Link Name}</a>
Link doesn't work for external links in gatsby