En el archivo _app podemos inyectarle anábolicos (providers, themes, props, o cualquier cosa que necesitemos) a toda nuestra aplicación.
Lo básico
Construir una web app con React no es fácil
Nuestro proyecto y lo que necesitaremos
Instalando NextJS
Routing
Rutas básicas
Rutas dinámicas
#UnderTheHood setup y páginas: optimizaciones ocultas
#UnderTheHood páginas: pre rendering de páginas
Enlazando páginas
#UnderTheHood enlazando páginas: prefetching automático
API y Debugging
¿Cómo crear API con NextJS?
Creando y consumiendo nuestra propia API
Extendiendo NextJS
Extendiendo el Document
Extendiendo el App
Path alias
Explora las soluciones de CSS en NextJS y su flexibilidad
Finalizando las páginas
Deployment en Vercel
Utilizando Vercel para hacer Deploy
Data Fetching y Pre-rendering
Introducción a los pre-render modes
#UnderTheHood Server Side Rendering: getServerSideProps
#UnderTheHood Static Generation: getStaticProps
#UnderTheHood Static Dynamic Static Generation: getStaticPaths
Deployment
Otras formas de hacer deploy de una app NextJS
Midiendo Performance
Mide Performance en NextJS
El futuro de NextJS
¿Qué será de NextJS en los próximos años?
Conclusiones
Continúa con el Curso de Next.js: Sitios Estáticos y Jamstack
Bonus Next.js 10
Next.js Image
Link y Proxy
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 25
Preguntas 5
En el archivo _app podemos inyectarle anábolicos (providers, themes, props, o cualquier cosa que necesitemos) a toda nuestra aplicación.
Todos los cambios en _app y _document, requieren reinicio de servidor.
En react 18 children fue eliminado del tipo FC, para que typescript no de error debes de añadirlo por cuenta propia
import React from 'react'
import { Navbar } from '@components/Navbar/Navbar'
type Props = {
children: React.ReactNode;
};
export const Layout: React.FC<Props> = ({ children }) => {
return (
<>
<Navbar />
{children}
<footer>
<p>This is a footer</p>
</footer>
</>
)
}
Documentación de Custom App:
https://nextjs.org/docs/advanced-features/custom-app
Casos de uso:
Y Que pasa si queremos tener dos layouts ejemplo la pagina login esa no tiene ni navbar ni footer como hacemos para tener dos o tres layouts ¿?
Esto hice para mostrar la página 404 sin el lay out.
import React from 'react';
import { useRouter } from 'next/router';
import Layout from '../src/components/Layout';
import AppContext from '../src/context/AppContext';
import useInitialState from '../src/hooks/useInitialState'
function MyApp({ Component, pageProps }) {
const router = useRouter();
const initialState = useInitialState();
return <AppContext.Provider value={initialState}><CustomLayout pathname={router.pathname}><Component {...pageProps} /></CustomLayout></AppContext.Provider>
}
const CustomLayout = ({ pathname, children }) => (
<>
{
pathname === "/_error" ? <>{children}</>
: (
<Layout>{children}</Layout>
)
}
</>
)
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
export default MyApp
documentación de Next.js para un custom app
Advanced Features: Custom App
| Next.js
La forma en la que Next.js renderiza en el navegador los contenidos es en el siguiente orden:
para usar el app de nuestra aplicación lo que haremos sera utilizar el template de la documentación de Next.js para un custom app, el cual debemos crear un archivo llamado “_app.js” en pages
import { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
// Providers - Context/Providers, Theme, data
// Layout
// props adicionales
return <Component {...pageProps} />
}
export default MyApp
RESUMEN: Para crear contenedores de nuestra aplicaciones, que deseemos aplicarlo a nivel global, es muy util usar el app de Next.js creando el archivo _app.js
Una opcion alternativa para los nombramientos de los componentes es ponerle el nombre a la carpeta y al archivo tsx llamarlo index . Es decir :
Layout >
index.tsx
Esto con el fin de que en el import se haga referencia a una ruta mas corta e igual de diciente que la que coloca Jonathan, asi:
import Layout from '../components/Layout
en vez de
import Layout from '../components/Layout/Layout';
NextJS primero renderiza el document
, luego el app
y ese app
es el que engloba nuestra aplicación.
Cuando hacemos cambios en app
o en document
debemos reiniciar el servidor.
Creamos un componente Layout:
import React from 'react'
import Navbar from 'components/Navbar/Navbar'
const Layout: React.FC = ({ children }) => {
return (
<div>
<Navbar />
{children}
<footer>This is the footer</footer>
</div>
)
}
export default Layout
Y lo usamos en ‘pages/_app.tsx’:
import type { AppProps } from 'next/app'
import Layout from '../components/Layout/Layout'
export default function MyApp({ Component, pageProps }: AppProps): JSX.Element {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
Segun la documentacion para typescript de custom app en nextjs
en este momento, inicialmente el archivo app.tsx viene quedando
import type { AppProps } from 'next/app'
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
A mi bo me funciono el React.FC, en este articulo explican porque no es buena práctica (Leí por ahí que su uso fue descontinuado) y que podemos usar en su lugar.
Cuando hacemos una aplicación con React, el archivo que contiene toda nuestra aplicación es el App.js, sin embargo, con NextJS no hace falta que lo creemos porque este ya viene por debajo con el. Pero qué pasa si queremos extender o cambiar la funcionalidad que viene por defecto?
Bueno en ese caso como vimos la extensión del document, también podemos extender lo que viene por defecto en el App.
Para eso, como lo hicimos con document creando el archivo document_.tsx || _document.jsx, debemos crear un archivo debajo de pages llamado _pages.jsx o .tsx.
Por qué es útil extender el app por defecto de next?
En el archivo _app que vamos a crear, debemos utilizar un template que la documentación oficial de NextJS nos proporciona
import { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default MyApp
En el caso de que lo usemos par crear un layout debe ser de la siguiente manera (suponiendo que el layout es el mismo para todas las páginas):
Layout.tsx:
import React from 'react';
const Layout: React.FC = ({children}) => {
<>
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
{children}
<footer>
All rights reserved
</footer>
</>
}
export default HomePage
App.tsx:
import { AppProps } from 'next/app'
import Layout from './Layout'
function MyApp({ Component, pageProps }: AppProps) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp
Qué pasa si para ciertas páginas deseemos usar un layout diferente? Como por ej, signup, login, splash screen, etc.
Para eso, tenemos que modificar el comportamiento de nuestro archivo _app por lo siguiente:
import DefaultLayout from "../layouts/default"
export default function MyApp({ Component, pageProps }) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout || ((page) => <DefaultLayout>{page}</DefaultLayout>)
return getLayout(<Component {...pageProps} />)
}
Aquí estamos diciendo que, si en el componente que se esta renderizando no hay un método ‘getLayout’, nos renderice un layout por defecto. Sin embargo, podemos usar un layout diferente con el método getLayout en la página que queramos, ahora que modificamos el _app:
Login.tsx
import React from 'react'
import InitialLayout from '../layouts/initial'
function Login() {
return (
<div>Login</div>
)
}
Login.getLayout = (page) => {
return (
<InitialLayout>{page}</InitialLayout>
)
}
export default Login;
El Login page, utiliza un método getLayout, que recibe el contenido de este, para que funcione debemos retornar un JSX, del layout deseado conteniendo al contenido de la página, que es el parámetro que recibe esta función.
RESUMEN: Para crear contenido global de nuestra aplicación, es recomendable extender el app de next
Jon! te fuiste un nivel .mas arriba del necesario para importar en NavBar
se podria hacer, ../Navbar/Navbar
directamente.
nada una boludez
import React, { ReactNode } from 'react';
import NavBar from '../Navbar/Navbar';
interface Props {
children: ReactNode;
}
const Layout = ({children}: Props) => {
return(
<div>
<NavBar />
{children}
<footer>soy el pie de pagina</footer>
</div>
);
}
export default Layout;```
tambien lo podemos hacer de la siguiente forma :D
Si estás usando TypeScript este es el código que pegas en el _app.tsx:
import type { AppProps } from 'next/app'
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
En el archivo _app.js yo he inyectado React Conext Providers dependiendo de la ruta. Aun ando aprendiendo del todo Next.js pero ha sido muy uutil esto de extender la funcionalidad de los componentes
Aca les dejo la documentación oficial para los que lo estén haciendo en las últimas versiones.
https://nextjs.org/docs/getting-started/installation#creating-directories
Si les marca error el children, solo tienen que tiparlo mediante una interface:
interface Props {
title: string;
children: JSX.Element
}
Después solo extienden el FC:
const Layout: FC<Props> = ({ children, title }) => {}
De forma explicita (sin usar React.FC) código en el layout:
import React from "react";
import { Navbar } from '../Navbar';
type Props = {
children?: JSX.Element;
};
function Layout({children}: Props) {
return (
<div>
<Navbar />
{children}
<footer>This is the footer</footer>
</div>
)
}
export { Layout }
Para quien tenga el error ‘‘Component’ cannot be used as a JSX component’, la solución es actualizar las dependencias de tipos de React a la versión 18.0.6.
el document en Typescript ahora es asi:
import Document, { DocumentContext, DocumentInitialProps } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
}
export default MyDocument
Actualmente la documentacion recomienda para typescrip el siguiente codigo
https://nextjs.org/docs/basic-features/typescript#custom-app
import type { AppProps } from 'next/app'
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
Dejo este articulo con ejemplos interesantes
https://jools.dev/nextjs-_appjs-example
Todo lo que pasen por las props del tag component queda disponible en las props de todos los hijos (es decir, de todos los componentes de la app:
return(
<Component {...pageProps} globalProp={algo} otraGlobalProp={otroAlgo} />
)
_app.tsx
// import App from 'next/app'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
export default MyApp
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.